├── src ├── util.ts ├── Menu.tsx ├── Box.tsx ├── BaseSVG.tsx ├── Image.tsx ├── Paragraph.tsx ├── BaseCode.tsx ├── BaseImage.tsx ├── BaseInput.tsx ├── BaseLabel.tsx ├── Ol.tsx ├── Tr.tsx ├── Ul.tsx ├── BaseAnchor.tsx ├── BaseButton.tsx ├── ManagedForm.tsx ├── BaseForm.tsx ├── Center.tsx ├── Badge.tsx ├── BaseTextArea.tsx ├── FormController.tsx ├── H2.tsx ├── H1.tsx ├── H3.tsx ├── H4.tsx ├── AspectRatio.tsx ├── Table.tsx ├── Td.tsx ├── Li.tsx ├── ErrorLabel.tsx ├── Checkbox.tsx ├── Text.tsx ├── Row.tsx ├── Col.tsx ├── DisclosureBox.tsx ├── Rule.tsx ├── RadioButton.tsx ├── StatelessCheckboxField.tsx ├── Label.tsx ├── StatelessToggleSwitchField.tsx ├── StatelessRadioButtonField.tsx ├── MenuItem.tsx ├── ContinuousProgressBar.tsx ├── Icon.tsx ├── BackgroundImage.tsx ├── DisclosureButton.tsx ├── StatelessTextArea.tsx ├── StatelessTextInput.tsx ├── Indicator.tsx ├── TwoUp.tsx ├── Action.tsx ├── ToggleSwitch.tsx ├── MenuList.tsx ├── Anchor.tsx ├── FourUp.tsx ├── ManagedTextAreaField.tsx ├── ManagedToggleSwitchField.tsx ├── SegmentedProgressBar.tsx ├── MenuButton.tsx ├── ManagedTextInputField.tsx ├── Button.tsx ├── Reset.tsx ├── ManagedCheckboxField.tsx ├── LoadingSpinner.tsx ├── ManagedRadioButtonField.tsx ├── system │ ├── unions.ts │ └── tokens.ts ├── index.tsx └── themes │ ├── dark.ts │ └── light.ts ├── docs ├── public │ ├── componentData │ │ ├── box.json │ │ ├── col.json │ │ ├── row.json │ │ ├── icon.json │ │ ├── menu.json │ │ ├── rule.json │ │ ├── text.json │ │ ├── label.json │ │ ├── reset.json │ │ ├── twoUp.json │ │ ├── button.json │ │ ├── center.json │ │ ├── fourUp.json │ │ ├── inline.json │ │ ├── baseSVG.json │ │ ├── checkbox.json │ │ ├── menuItem.json │ │ ├── menuList.json │ │ ├── baseCode.json │ │ ├── baseForm.json │ │ ├── baseInput.json │ │ ├── baseLabel.json │ │ ├── indicator.json │ │ ├── errorLabel.json │ │ ├── menuButton.json │ │ ├── managedForm.json │ │ ├── radioButton.json │ │ ├── baseTextArea.json │ │ ├── buttonAnchor.json │ │ ├── toggleSwitch.json │ │ ├── aspectRatio.json │ │ ├── disclosureBox.json │ │ ├── action.json │ │ ├── formController.json │ │ ├── loadingSpinner.json │ │ ├── disclosureButton.json │ │ ├── statelessTextArea.json │ │ ├── statelessTextInput.json │ │ ├── baseButton.json │ │ ├── anchor.json │ │ ├── managedCheckboxField.json │ │ ├── managedTextAreaField.json │ │ ├── segmentedProgressBar.json │ │ ├── continuousProgressBar.json │ │ ├── managedTextInputField.json │ │ ├── statelessCheckboxField.json │ │ ├── managedRadioButtonField.json │ │ ├── baseAnchor.json │ │ ├── baseImage.json │ │ ├── managedToggleSwitchField.json │ │ ├── statelessRadioButtonField.json │ │ ├── actionAnchor.json │ │ ├── statelessToggleSwitchField.json │ │ └── backgroundImage.json │ ├── index.html │ └── manifest.json ├── src │ ├── assets │ │ └── indigoIcon.png │ ├── index.tsx │ ├── pages │ │ ├── Home.tsx │ │ └── ComponentPage.tsx │ ├── types.ts │ ├── components │ │ ├── Header.tsx │ │ ├── VersionTag.tsx │ │ ├── SidebarAnchor.tsx │ │ ├── SidebarLink.tsx │ │ ├── IndigoIcon.tsx │ │ ├── Sidebar.tsx │ │ └── ComponentPreview.tsx │ ├── constants.ts │ └── App.tsx ├── tsconfig.json └── package.json ├── .editorconfig ├── .npmignore ├── .gitignore ├── examples ├── tsconfig.json ├── public │ └── index.html ├── package.json └── src │ └── index.tsx ├── .github └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── LICENSE ├── tsconfig.json ├── scripts ├── generate_docs.js └── temp_migrate.js ├── package.json ├── README.md ├── CHANGELOG └── DEVELOPMENT.md /src/util.ts: -------------------------------------------------------------------------------- 1 | export const sequence = (num: number) => Array.from(Array(num), (_, i) => i); 2 | -------------------------------------------------------------------------------- /docs/public/componentData/box.json: -------------------------------------------------------------------------------- 1 | { "id": "box", "displayName": "Box", "snippet": " ", "props": [] } 2 | -------------------------------------------------------------------------------- /docs/public/componentData/col.json: -------------------------------------------------------------------------------- 1 | { "id": "col", "displayName": "Col", "snippet": " ", "props": [] } 2 | -------------------------------------------------------------------------------- /docs/public/componentData/row.json: -------------------------------------------------------------------------------- 1 | { "id": "row", "displayName": "Row", "snippet": " ", "props": [] } 2 | -------------------------------------------------------------------------------- /docs/src/assets/indigoIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tloncorp/indigo-react/HEAD/docs/src/assets/indigoIcon.png -------------------------------------------------------------------------------- /docs/public/componentData/icon.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "icon", 3 | "displayName": "Icon", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/menu.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "menu", 3 | "displayName": "Menu", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/rule.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "rule", 3 | "displayName": "Rule", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/text.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "text", 3 | "displayName": "Text", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/label.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "label", 3 | "displayName": "Label", 4 | "snippet": "", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/reset.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "reset", 3 | "displayName": "Reset", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/twoUp.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "twoUp", 3 | "displayName": "TwoUp", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/button.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "button", 3 | "displayName": "Button", 4 | "snippet": "", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/center.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "center", 3 | "displayName": "Center", 4 | "snippet": "
", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/fourUp.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "fourUp", 3 | "displayName": "FourUp", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/inline.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "inline", 3 | "displayName": "Inline", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/baseSVG.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "baseSVG", 3 | "displayName": "BaseSVG", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/checkbox.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "checkbox", 3 | "displayName": "Checkbox", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/menuItem.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "menuItem", 3 | "displayName": "MenuItem", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/menuList.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "menuList", 3 | "displayName": "MenuList", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/baseCode.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "baseCode", 3 | "displayName": "BaseCode", 4 | "snippet": "BaseCode", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/baseForm.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "baseForm", 3 | "displayName": "BaseForm", 4 | "snippet": "BaseForm", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/baseInput.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "baseInput", 3 | "displayName": "BaseInput", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/baseLabel.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "baseLabel", 3 | "displayName": "BaseLabel", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/indicator.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "indicator", 3 | "displayName": "Indicator", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/errorLabel.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "errorLabel", 3 | "displayName": "ErrorLabel", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/menuButton.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "menuButton", 3 | "displayName": "MenuButton", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/managedForm.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "managedForm", 3 | "displayName": "ManagedForm", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/radioButton.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "radioButton", 3 | "displayName": "RadioButton", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/baseTextArea.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "baseTextArea", 3 | "displayName": "BaseTextArea", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/buttonAnchor.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "buttonAnchor", 3 | "displayName": "ButtonAnchor", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/toggleSwitch.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "toggleSwitch", 3 | "displayName": "ToggleSwitch", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/aspectRatio.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "aspectRatio", 3 | "displayName": "AspectRatio", 4 | "snippet": "", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/disclosureBox.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "disclosureBox", 3 | "displayName": "DisclosureBox", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/src/index.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import * as ReactDOM from "react-dom"; 3 | import { App } from "./App"; 4 | 5 | ReactDOM.render(, document.getElementById("root")); 6 | -------------------------------------------------------------------------------- /docs/public/componentData/action.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "action", 3 | "displayName": "Action", 4 | "snippet": " console.log('Action')}>Action", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/formController.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "formController", 3 | "displayName": "FormController", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/loadingSpinner.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "loadingSpinner", 3 | "displayName": "LoadingSpinner", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /docs/src/pages/Home.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { Link } from "react-router-dom"; 3 | import { Col, Text } from "local-indigo-react"; 4 | 5 | export const Home = () => ; 6 | -------------------------------------------------------------------------------- /docs/public/componentData/disclosureButton.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "disclosureButton", 3 | "displayName": "DisclosureButton", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/statelessTextArea.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "statelessTextArea", 3 | "displayName": "StatelessTextArea", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/statelessTextInput.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "statelessTextInput", 3 | "displayName": "StatelessTextInput", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/baseButton.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "baseButton", 3 | "displayName": "BaseButton", 4 | "snippet": " console.log('Hello')}>BaseButton", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/anchor.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "anchor", 3 | "displayName": "Anchor", 4 | "snippet": "Indigo React", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/managedCheckboxField.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "managedCheckboxField", 3 | "displayName": "ManagedCheckboxField", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/managedTextAreaField.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "managedTextAreaField", 3 | "displayName": "ManagedTextAreaField", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/segmentedProgressBar.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "segmentedProgressBar", 3 | "displayName": "SegmentedProgressBar", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/continuousProgressBar.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "continuousProgressBar", 3 | "displayName": "ContinuousProgressBar", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/managedTextInputField.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "managedTextInputField", 3 | "displayName": "ManagedTextInputField", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/statelessCheckboxField.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "statelessCheckboxField", 3 | "displayName": "StatelessCheckboxField", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/managedRadioButtonField.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "managedRadioButtonField", 3 | "displayName": "ManagedRadioButtonField", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/baseAnchor.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "baseAnchor", 3 | "displayName": "BaseAnchor", 4 | "snippet": "Indigo React", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/baseImage.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "baseImage", 3 | "displayName": "BaseImage", 4 | "snippet": "", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/managedToggleSwitchField.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "managedToggleSwitchField", 3 | "displayName": "ManagedToggleSwitchField", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/statelessRadioButtonField.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "statelessRadioButtonField", 3 | "displayName": "StatelessRadioButtonField", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/actionAnchor.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "actionAnchor", 3 | "displayName": "ActionAnchor", 4 | "snippet": "Indigo React", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/statelessToggleSwitchField.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "statelessToggleSwitchField", 3 | "displayName": "StatelessToggleSwitchField", 4 | "snippet": " ", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/componentData/backgroundImage.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "backgroundImage", 3 | "displayName": "BackgroundImage", 4 | "snippet": "", 5 | "props": [] 6 | } 7 | -------------------------------------------------------------------------------- /src/Menu.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import { 3 | Menu as ReachMenu, 4 | MenuProps as ReachMenuProps, 5 | } from "@reach/menu-button"; 6 | 7 | export type MenuProps = ReachMenuProps; 8 | 9 | export const Menu = styled(ReachMenu)` 10 | display: block; 11 | position: absolute; 12 | `; 13 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | node_modules 3 | 4 | # builds 5 | build 6 | dist 7 | .rpt2_cache 8 | 9 | # misc 10 | .DS_Store 11 | .env 12 | .env.local 13 | .env.development.local 14 | .env.test.local 15 | .env.production.local 16 | 17 | npm-debug.log* 18 | yarn-debug.log* 19 | yarn-error.log* 20 | 21 | .cache 22 | example 23 | -------------------------------------------------------------------------------- /docs/src/types.ts: -------------------------------------------------------------------------------- 1 | export type ComponentProperties = { 2 | id: string; 3 | displayName: string; 4 | snippet: string; 5 | props: []; 6 | }; 7 | 8 | export type ComponentEntry = { 9 | id: string; 10 | displayName: string; 11 | }; 12 | 13 | export type Manifest = { 14 | componentCount: number; 15 | components: ComponentEntry[]; 16 | }; 17 | -------------------------------------------------------------------------------- /src/Box.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import { compose } from "styled-system"; 3 | import { allSystemStyle, AllSystemProps } from "./system/unions"; 4 | 5 | export type BoxProps = AllSystemProps; 6 | 7 | export const Box = styled.div>( 8 | compose(...allSystemStyle) 9 | ); 10 | 11 | Box.displayName = "Box"; 12 | -------------------------------------------------------------------------------- /src/BaseSVG.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import { compose } from "styled-system"; 3 | import { allSystemStyle, AllSystemProps } from "./system/unions"; 4 | 5 | export type BaseSVGProps = AllSystemProps; 6 | 7 | export const BaseSVG = styled.svg>( 8 | compose(...allSystemStyle) 9 | ); 10 | 11 | BaseSVG.displayName = "BaseSVG"; 12 | -------------------------------------------------------------------------------- /src/Image.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import { allSystemStyle, AllSystemProps } from "./system/unions"; 3 | 4 | export type ImageProps = AllSystemProps; 5 | 6 | export const Image = styled.img>( 7 | { 8 | width: "100%", 9 | height: "auto", 10 | }, 11 | ...allSystemStyle 12 | ); 13 | 14 | Image.displayName = "Image"; 15 | -------------------------------------------------------------------------------- /src/Paragraph.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import styled from "styled-components"; 3 | import { commonStyle, CommonStyleProps } from "./system/unions"; 4 | 5 | export type ParagraphProps = CommonStyleProps; 6 | 7 | export const Paragraph = styled.p>( 8 | {}, 9 | ...commonStyle 10 | ); 11 | 12 | Paragraph.displayName = "Paragraph"; 13 | -------------------------------------------------------------------------------- /src/BaseCode.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import { compose } from "styled-system"; 3 | import { allSystemStyle, AllSystemProps } from "./system/unions"; 4 | 5 | export type BaseCodeProps = AllSystemProps; 6 | 7 | export const BaseCode = styled.code>( 8 | compose(...allSystemStyle) 9 | ); 10 | 11 | BaseCode.displayName = "BaseCode"; 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | node_modules 5 | 6 | # builds 7 | build 8 | dist 9 | .rpt2_cache 10 | 11 | # misc 12 | .DS_Store 13 | .env 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | 23 | .cache 24 | -------------------------------------------------------------------------------- /examples/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "module": "commonjs", 5 | "sourceMap": true, 6 | "outDir": "dist", 7 | "jsx": "react", 8 | "skipLibCheck": true, 9 | // "declaration": true, 10 | "strict": true, 11 | "noImplicitReturns": true, 12 | "noFallthroughCasesInSwitch": true 13 | }, 14 | "files": ["src/index.tsx"] 15 | } 16 | -------------------------------------------------------------------------------- /src/BaseImage.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import { compose } from "styled-system"; 3 | import { allSystemStyle, AllSystemProps } from "./system/unions"; 4 | 5 | export type BaseImageProps = AllSystemProps; 6 | 7 | export const BaseImage = styled.img>( 8 | compose(...allSystemStyle) 9 | ); 10 | 11 | BaseImage.displayName = "BaseImage"; 12 | -------------------------------------------------------------------------------- /src/BaseInput.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import { compose } from "styled-system"; 3 | import { allSystemStyle, AllSystemProps } from "./system/unions"; 4 | 5 | export type BaseInputProps = AllSystemProps; 6 | 7 | export const BaseInput = styled.input>( 8 | compose(...allSystemStyle) 9 | ); 10 | 11 | BaseInput.displayName = "BaseInput"; 12 | -------------------------------------------------------------------------------- /src/BaseLabel.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import { compose } from "styled-system"; 3 | import { allSystemStyle, AllSystemProps } from "./system/unions"; 4 | 5 | export type BaseLabelProps = AllSystemProps; 6 | 7 | export const BaseLabel = styled.label>( 8 | compose(...allSystemStyle) 9 | ); 10 | 11 | BaseLabel.displayName = "BaseLabel"; 12 | -------------------------------------------------------------------------------- /src/Ol.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import { compose } from "styled-system"; 3 | import { listStyle, ListProps } from "./system/unions"; 4 | 5 | export type OlProps = ListProps; 6 | 7 | export const Ol = styled.ol>( 8 | compose(...listStyle) 9 | ); 10 | 11 | Ol.defaultProps = { 12 | listStyle: 'decimal' 13 | } 14 | 15 | Ol.displayName = "Ol"; 16 | -------------------------------------------------------------------------------- /src/Tr.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import { compose } from "styled-system"; 3 | import { allSystemStyle, AllSystemProps } from "./system/unions"; 4 | 5 | export type TrProps = AllSystemProps & React.HTMLAttributes; 6 | 7 | export const Tr = styled.tr>( 8 | compose(...allSystemStyle) 9 | ); 10 | 11 | Tr.displayName = "Tr"; 12 | -------------------------------------------------------------------------------- /src/Ul.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import { compose } from "styled-system"; 3 | import { listStyle, ListProps } from "./system/unions"; 4 | 5 | export type UlProps = ListProps; 6 | 7 | export const Ul = styled.ul>( 8 | compose(...listStyle) 9 | ); 10 | 11 | Ul.defaultProps = { 12 | listStyle: 'disc' 13 | } 14 | 15 | Ul.displayName = "Ul"; 16 | -------------------------------------------------------------------------------- /src/BaseAnchor.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import { compose } from "styled-system"; 3 | import { allSystemStyle, AllSystemProps } from "./system/unions"; 4 | 5 | export type BaseAnchorProps = AllSystemProps; 6 | 7 | export const BaseAnchor = styled.a>( 8 | compose(...allSystemStyle) 9 | ); 10 | 11 | BaseAnchor.displayName = "BaseAnchor"; 12 | -------------------------------------------------------------------------------- /src/BaseButton.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import { compose } from "styled-system"; 3 | import { allSystemStyle, AllSystemProps } from "./system/unions"; 4 | 5 | export type BaseButtonProps = AllSystemProps; 6 | 7 | export const BaseButton = styled.button< 8 | React.PropsWithChildren 9 | >(compose(...allSystemStyle)); 10 | 11 | BaseButton.displayName = "BaseButton"; 12 | -------------------------------------------------------------------------------- /docs/src/components/Header.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | // import { Link } from "react-router-dom"; 3 | import { Row, Text } from "local-indigo-react"; 4 | 5 | export const Header = () => ( 6 | 13 | Indigo Documentation 14 | 15 | ); 16 | -------------------------------------------------------------------------------- /src/ManagedForm.tsx: -------------------------------------------------------------------------------- 1 | import { Form as FormikForm } from "formik"; 2 | import styled from "styled-components"; 3 | import { structureStyle, StructureProps } from "./system/unions"; 4 | 5 | export type ManagedFormProps = StructureProps; 6 | 7 | export const ManagedForm = styled(FormikForm)< 8 | React.PropsWithChildren 9 | >({}, ...structureStyle); 10 | 11 | ManagedForm.displayName = "ManagedForm"; 12 | -------------------------------------------------------------------------------- /docs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "module": "commonjs", 5 | "sourceMap": true, 6 | "outDir": "dist", 7 | "jsx": "react", 8 | "skipLibCheck": true, 9 | "strict": true, 10 | "noImplicitReturns": true, 11 | "noFallthroughCasesInSwitch": true, 12 | "resolveJsonModule": true, 13 | "esModuleInterop": true 14 | }, 15 | "files": ["src/index.tsx"] 16 | } 17 | -------------------------------------------------------------------------------- /src/BaseForm.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import { compose } from "styled-system"; 3 | import { allSystemStyle, AllSystemProps } from "./system/unions"; 4 | 5 | export type BaseFormProps = AllSystemProps; 6 | 7 | const styleProps = compose(...allSystemStyle); 8 | 9 | export const BaseForm = styled.textarea>( 10 | styleProps 11 | ); 12 | 13 | BaseForm.displayName = "BaseForm"; 14 | -------------------------------------------------------------------------------- /src/Center.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import { structureStyle, StructureProps } from "./system/unions"; 3 | 4 | export type CenterProps = StructureProps; 5 | 6 | export const Center = styled.div>( 7 | { 8 | display: "flex", 9 | alignItems: "center", 10 | justifyContent: "center", 11 | }, 12 | ...structureStyle 13 | ); 14 | 15 | Center.displayName = "Center"; 16 | -------------------------------------------------------------------------------- /src/Badge.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { Text, TextProps } from "./index"; 3 | 4 | type BadgeProps = TextProps; 5 | 6 | export const Badge = (props: BadgeProps) => ( 7 | 19 | ); 20 | -------------------------------------------------------------------------------- /src/BaseTextArea.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import { compose } from "styled-system"; 3 | import { allSystemStyle, AllSystemProps } from "./system/unions"; 4 | 5 | export type BaseTextAreaProps = AllSystemProps; 6 | 7 | const styleProps = compose(...allSystemStyle); 8 | 9 | export const BaseTextArea = styled.textarea< 10 | React.PropsWithChildren 11 | >(styleProps); 12 | 13 | BaseTextArea.displayName = "BaseTextArea"; 14 | -------------------------------------------------------------------------------- /src/FormController.tsx: -------------------------------------------------------------------------------- 1 | import { Formik } from "formik"; 2 | import styled from "styled-components"; 3 | import { compose } from "styled-system"; 4 | import { CommonStyleProps, commonStyle } from "./system/unions"; 5 | 6 | export type FormControllerProps = CommonStyleProps; 7 | 8 | export const FormController = styled(Formik)< 9 | React.PropsWithChildren 10 | >` 11 | ${compose(...commonStyle)} 12 | `; 13 | 14 | FormController.displayName = "FormController"; 15 | -------------------------------------------------------------------------------- /docs/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 11 | 12 | 13 | Indigo Docs 14 | 15 | 16 | 17 | 20 | 21 |
22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /examples/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 11 | 12 | 13 | local-indigo-react 14 | 15 | 16 | 17 | 20 | 21 |
22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/H2.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import css, { SystemStyleObject } from "@styled-system/css"; 3 | import { AllSystemProps, allSystemStyle } from "./system/unions"; 4 | 5 | export type H2Props = AllSystemProps & { 6 | mono?: boolean; 7 | }; 8 | 9 | const style = ({ mono = false }: H2Props) => 10 | css({ 11 | fontWeight: "bold", 12 | color: "black", 13 | fontFamily: mono ? "mono" : "sans", 14 | lineHeight: "min", 15 | fontSize: 3, 16 | } as SystemStyleObject); 17 | 18 | export const H2 = styled.span>( 19 | style, 20 | ...allSystemStyle 21 | ); 22 | 23 | H2.displayName = "H2"; 24 | -------------------------------------------------------------------------------- /src/H1.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import css, { SystemStyleObject } from "@styled-system/css"; 3 | import { AllSystemProps, allSystemStyle } from "./system/unions"; 4 | 5 | export type H1Props = AllSystemProps & { 6 | mono?: boolean; 7 | }; 8 | 9 | const style = ({ mono = false }: H1Props) => 10 | css({ 11 | fontWeight: "bold", 12 | color: "black", 13 | fontFamily: mono ? "mono" : "sans", 14 | lineHeight: "short", 15 | fontSize: 4, 16 | } as SystemStyleObject); 17 | 18 | export const H1 = styled.span>( 19 | style, 20 | ...allSystemStyle 21 | ); 22 | 23 | H1.displayName = "H1"; 24 | -------------------------------------------------------------------------------- /src/H3.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import css, { SystemStyleObject } from "@styled-system/css"; 3 | import { AllSystemProps, allSystemStyle } from "./system/unions"; 4 | 5 | export type H3Props = AllSystemProps & { 6 | mono?: boolean; 7 | }; 8 | 9 | const style = ({ mono = false }: H3Props) => 10 | css({ 11 | fontWeight: "bold", 12 | color: "black", 13 | fontFamily: mono ? "mono" : "sans", 14 | lineHeight: "short", 15 | fontSize: 2, 16 | } as SystemStyleObject); 17 | 18 | export const H3 = styled.span>( 19 | style, 20 | ...allSystemStyle 21 | ); 22 | 23 | H3.displayName = "H3"; 24 | -------------------------------------------------------------------------------- /src/H4.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import css, { SystemStyleObject } from "@styled-system/css"; 3 | import { AllSystemProps, allSystemStyle } from "./system/unions"; 4 | 5 | export type H4Props = AllSystemProps & { 6 | mono?: boolean; 7 | }; 8 | 9 | const style = ({ mono = false }: H4Props) => 10 | css({ 11 | fontWeight: "bold", 12 | color: "black", 13 | fontFamily: mono ? "mono" : "sans", 14 | lineHeight: "short", 15 | fontSize: 1, 16 | } as SystemStyleObject); 17 | 18 | export const H4 = styled.span>( 19 | style, 20 | ...allSystemStyle 21 | ); 22 | 23 | H4.displayName = "H4"; 24 | -------------------------------------------------------------------------------- /src/AspectRatio.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { Box } from "./Box"; 3 | import { CommonStyleProps } from "./system/unions"; 4 | 5 | export type AspectRatioProps = CommonStyleProps & 6 | React.HTMLAttributes & { 7 | aspectRatio: number; 8 | }; 9 | 10 | export const AspectRatio = ({ 11 | aspectRatio = 1, 12 | children, 13 | }: AspectRatioProps) => { 14 | const percent = `${(1 / aspectRatio) * 100}%`; 15 | 16 | return ( 17 | 18 | 19 | {children} 20 | 21 | 22 | ); 23 | }; 24 | 25 | AspectRatio.displayName = "AspectRatio"; 26 | -------------------------------------------------------------------------------- /src/Table.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import styled from "styled-components"; 3 | import css, { SystemStyleObject } from "@styled-system/css"; 4 | import { allSystemStyle, AllSystemProps } from "./system/unions"; 5 | 6 | export type TableProps = AllSystemProps & 7 | React.HTMLAttributes; 8 | 9 | const style = () => 10 | css({ 11 | borderLeft: "1px solid", 12 | borderTop: "1px solid", 13 | borderColor: "lightGray", 14 | borderCollapse: "separate", 15 | } as SystemStyleObject); 16 | 17 | export const Table = styled.table>( 18 | style, 19 | ...allSystemStyle 20 | ); 21 | 22 | Table.displayName = "Table"; 23 | -------------------------------------------------------------------------------- /src/Td.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import styled from "styled-components"; 3 | import css, { SystemStyleObject } from "@styled-system/css"; 4 | import { allSystemStyle, AllSystemProps } from "./system/unions"; 5 | 6 | export type TdProps = AllSystemProps & 7 | React.HTMLAttributes; 8 | 9 | const style = () => 10 | css({ 11 | p: 1, 12 | borderRight: "1px solid", 13 | borderBottom: "1px solid", 14 | borderRightColor: "lightGray", 15 | borderBottomColor: "lightGray", 16 | } as SystemStyleObject); 17 | 18 | export const Td = styled.td>( 19 | style, 20 | ...allSystemStyle 21 | ); 22 | 23 | Td.displayName = "Td"; 24 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /docs/src/constants.ts: -------------------------------------------------------------------------------- 1 | export const links = { 2 | reactNPM: "https://www.npmjs.com/package/@tlon/indigo-react", 3 | reactGithub: "https://github.com/urbit/indigo-react", 4 | tokensNPM: "https://www.npmjs.com/package/@tlon/indigo-light", 5 | tokensGithub: "https://github.com/urbit/indigo-tokens", 6 | figma: "https://www.figma.com/file/H1RAHV4KscSTnvrIiL0z8C/Indigo", 7 | }; 8 | 9 | // @ts-ignore 10 | export const baseURL = 11 | process.env.NODE_ENV === "development" 12 | ? "http://localhost:1234" 13 | : "https://indigo.urbit.org"; 14 | 15 | // @ts-ignore 16 | // export const assetUrl = process.env.NODE_ENV === 'development' 17 | // ? 'http://localhost:1234' 18 | // : 'https://indigo.urbit.org' 19 | -------------------------------------------------------------------------------- /src/Li.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import css, { SystemStyleObject } from "@styled-system/css"; 3 | import { allSystemStyle, AllSystemProps } from "./system/unions"; 4 | 5 | export type LiProps = AllSystemProps; 6 | 7 | const style = ({ color, fontFamily, fontSize }: LiProps) => 8 | css({ 9 | "&::marker": { 10 | color: typeof color === "undefined" ? "black" : color, 11 | fontFamily: typeof fontFamily === "undefined" ? "sans" : fontFamily, 12 | fontSize: typeof fontSize === "undefined" ? 1 : fontSize 13 | }, 14 | } as SystemStyleObject); 15 | 16 | export const Li = styled.li>( 17 | style, ...allSystemStyle 18 | ); 19 | 20 | Li.displayName = "Li"; 21 | -------------------------------------------------------------------------------- /src/ErrorLabel.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { Icon, Label, Box } from "./index"; 3 | import { CommonStyleProps } from "./system/unions"; 4 | 5 | export type ErrorLabelProps = CommonStyleProps & { 6 | hasError?: boolean; 7 | }; 8 | 9 | export const ErrorLabel = ({ 10 | hasError, 11 | children, 12 | ...props 13 | }: ErrorLabelProps & React.HTMLAttributes) => ( 14 | 15 | 22 | 23 | 24 | ); 25 | 26 | ErrorLabel.displayName = "ErrorLabel"; 27 | -------------------------------------------------------------------------------- /src/Checkbox.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { Indicator } from "./Indicator"; 3 | import { Icon } from "./Icon"; 4 | import { StructureProps } from "./system/unions"; 5 | 6 | export type CheckboxProps = StructureProps & { 7 | selected?: boolean; 8 | hasError?: boolean; 9 | disabled?: boolean; 10 | } & React.HTMLAttributes; 11 | 12 | export const Checkbox = ({ 13 | selected, 14 | disabled, 15 | hasError, 16 | ...props 17 | }: CheckboxProps) => { 18 | return ( 19 | 25 | 26 | 27 | ); 28 | }; 29 | 30 | Checkbox.displayName = "Checkbox"; 31 | -------------------------------------------------------------------------------- /src/Text.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import css, { SystemStyleObject } from "@styled-system/css"; 3 | import { AllSystemProps, allSystemStyle } from "./system/unions"; 4 | 5 | export type TextProps = AllSystemProps & { 6 | gray?: boolean; 7 | bold?: boolean; 8 | mono?: boolean; 9 | }; 10 | 11 | const style = ({ gray = false, bold = false, mono = false }: TextProps) => 12 | css({ 13 | fontWeight: bold ? "bold" : "regular", 14 | color: gray ? "gray" : "black", 15 | fontFamily: mono ? "mono" : "sans", 16 | lineHeight: "short", 17 | minHeight: "3", 18 | fontSize: 1, 19 | } as SystemStyleObject); 20 | 21 | export const Text = styled.span>( 22 | style, 23 | ...allSystemStyle 24 | ); 25 | 26 | Text.displayName = "Text"; 27 | -------------------------------------------------------------------------------- /docs/src/components/VersionTag.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import css, { SystemStyleObject } from "@styled-system/css"; 3 | import { commonStyle, CommonStyleProps, Label } from "local-indigo-react"; 4 | 5 | export type VersionTagProps = CommonStyleProps & { 6 | disabled?: boolean; 7 | destructive?: boolean; 8 | }; 9 | 10 | const style = () => 11 | css({ 12 | fontFeatureSettings: "'tnum' on, 'lnum' on, 'zero' on, 'ss01' on", 13 | fontFamily: "mono", 14 | px: "2", 15 | height: "4", 16 | color: "blue", 17 | bg: "washedBlue", 18 | borderRadius: "2", 19 | border: "1px solid", 20 | borderColor: "washedBlue", 21 | } as SystemStyleObject); 22 | 23 | export const VersionTag = styled(Label)< 24 | React.PropsWithChildren 25 | >(style, ...commonStyle); 26 | -------------------------------------------------------------------------------- /src/Row.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import styled from "styled-components"; 3 | import css, { SystemStyleObject } from "@styled-system/css"; 4 | import { ResponsiveValue, ThemeValue, RequiredTheme } from "styled-system"; 5 | import { AllSystemProps, allSystemStyle } from "./system/unions"; 6 | 7 | export type RowProps = AllSystemProps & { 8 | gapX?: ResponsiveValue>; 9 | }; 10 | 11 | const style = ({ gapX }: RowProps) => 12 | css({ 13 | display: "flex", 14 | "& > *": typeof gapX === "undefined" ? {} : { marginRight: gapX }, 15 | "& > :last-child": typeof gapX === "undefined" ? {} : { marginRight: 0 }, 16 | } as SystemStyleObject); 17 | 18 | export const Row = styled.div>( 19 | style, 20 | ...allSystemStyle 21 | ); 22 | 23 | Row.displayName = "Row"; 24 | -------------------------------------------------------------------------------- /src/Col.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import styled from "styled-components"; 3 | import css, { SystemStyleObject } from "@styled-system/css"; 4 | import { ResponsiveValue, ThemeValue, RequiredTheme } from "styled-system"; 5 | import { AllSystemProps, allSystemStyle } from "./system/unions"; 6 | 7 | export type ColProps = AllSystemProps & { 8 | gapY?: ResponsiveValue>; 9 | }; 10 | 11 | const style = ({ gapY }: ColProps) => 12 | css({ 13 | display: "flex", 14 | flexDirection: "column", 15 | "& > *": typeof gapY === "undefined" ? {} : { marginTop: gapY }, 16 | "& > :first-child": typeof gapY === "undefined" ? {} : { marginTop: 0 }, 17 | } as SystemStyleObject); 18 | 19 | export const Col = styled.div>( 20 | style, 21 | ...allSystemStyle 22 | ); 23 | 24 | Col.displayName = "Col"; 25 | -------------------------------------------------------------------------------- /src/DisclosureBox.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import styled from "styled-components"; 3 | import css, { SystemStyleObject } from "@styled-system/css"; 4 | import { AllSystemProps, allSystemStyle } from "./system/unions"; 5 | 6 | export type DisclosureBoxProps = AllSystemProps & { 7 | isOpen?: boolean; 8 | }; 9 | 10 | const style = ({ isOpen }: DisclosureBoxProps) => 11 | css({ 12 | display: isOpen ? "flex" : "none", 13 | flexDirection: "column", 14 | visibility: isOpen ? "visible" : "hidden", 15 | borderLeft: isOpen ? "1px solid" : "none", 16 | borderColor: isOpen ? "lightGray" : "transparent", 17 | padding: 2, 18 | mx: 3, 19 | } as SystemStyleObject); 20 | 21 | export const DisclosureBox = styled.div< 22 | React.PropsWithChildren 23 | >(style, ...allSystemStyle); 24 | 25 | DisclosureBox.displayName = "DisclosureBox"; 26 | -------------------------------------------------------------------------------- /src/Rule.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import { ColorProps, color } from "styled-system"; 3 | import css, { SystemStyleObject } from "@styled-system/css"; 4 | import { StructureProps, structureStyle } from "./system/unions"; 5 | 6 | export type RuleProps = ColorProps & 7 | StructureProps & { 8 | vertical?: boolean; 9 | }; 10 | 11 | const style = ({ vertical = false }: RuleProps) => 12 | css({ 13 | height: vertical ? "auto" : 0, 14 | width: vertical ? 0 : "100%", 15 | borderWidth: 0, 16 | borderStyle: "solid", 17 | borderTopWidth: vertical ? 0 : "1px", 18 | borderLeftWidth: vertical ? "1px" : 0, 19 | borderColor: "lightGray", 20 | } as SystemStyleObject); 21 | 22 | export const Rule = styled.div>( 23 | style, 24 | color, 25 | ...structureStyle 26 | ); 27 | 28 | Rule.displayName = "Rule"; 29 | -------------------------------------------------------------------------------- /src/RadioButton.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { Indicator } from "./Indicator"; 3 | import { Icon } from "./Icon"; 4 | import { StructureProps } from "./system/unions"; 5 | 6 | export type RadioButtonProps = StructureProps & { 7 | selected?: boolean; 8 | hasError?: boolean; 9 | disabled?: boolean; 10 | name: string; 11 | } & React.HTMLAttributes; 12 | 13 | export const RadioButton = ({ 14 | selected, 15 | disabled, 16 | hasError, 17 | onChange, 18 | name, 19 | children, 20 | ...props 21 | }: RadioButtonProps) => { 22 | return ( 23 | 30 | 31 | 32 | ); 33 | }; 34 | 35 | RadioButton.displayName = "RadioButton"; 36 | -------------------------------------------------------------------------------- /docs/src/components/SidebarAnchor.tsx: -------------------------------------------------------------------------------- 1 | import { Link } from "react-router-dom"; 2 | import styled from "styled-components"; 3 | import css, { SystemStyleObject } from "@styled-system/css"; 4 | import { commonStyle, CommonStyleProps } from "local-indigo-react"; 5 | 6 | export type SidebarAnchorProps = CommonStyleProps & { 7 | disabled?: boolean; 8 | destructive?: boolean; 9 | }; 10 | const style = () => 11 | css({ 12 | width: "auto", 13 | border: "none", 14 | overflow: "hidden", 15 | minHeight: 5, 16 | display: "flex", 17 | alignItems: "center", 18 | fontFamily: "sans", 19 | color: "gray", 20 | fontSize: 1, 21 | borderRight: "1px solid", 22 | borderRightColor: "lightGray", 23 | textDecoration: "none", 24 | } as SystemStyleObject); 25 | 26 | export const SidebarAnchor = styled.a< 27 | React.PropsWithChildren 28 | >(style, ...commonStyle); 29 | -------------------------------------------------------------------------------- /docs/src/App.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom"; 3 | import { Row, Col, Text, Reset, _light as light } from "local-indigo-react"; 4 | import { ThemeProvider } from "styled-components"; 5 | import { Home } from "./pages/Home"; 6 | import { ComponentPage } from "./pages/ComponentPage"; 7 | import { Sidebar } from "./components/Sidebar"; 8 | 9 | export const App = () => { 10 | return ( 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | ); 26 | }; 27 | -------------------------------------------------------------------------------- /src/StatelessCheckboxField.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { Checkbox, Box, Col } from "./index"; 3 | import { StructureProps } from "./system/unions"; 4 | 5 | export type StatelessCheckboxFieldProps = { 6 | selected?: boolean; 7 | hasError?: boolean; 8 | disabled?: boolean; 9 | } & React.HTMLAttributes & 10 | StructureProps; 11 | 12 | export const StatelessCheckboxField = ({ 13 | selected, 14 | disabled, 15 | hasError, 16 | onChange, 17 | children, 18 | ...props 19 | }: StatelessCheckboxFieldProps) => { 20 | return ( 21 | 22 | 28 | {children} 29 | 30 | ); 31 | }; 32 | 33 | StatelessCheckboxField.displayName = "StatelessCheckboxField"; 34 | -------------------------------------------------------------------------------- /src/Label.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import css, { SystemStyleObject } from "@styled-system/css"; 3 | import { commonStyle, CommonStyleProps } from "./system/unions"; 4 | 5 | export type LabelProps = CommonStyleProps & { 6 | gray?: boolean; 7 | bold?: boolean; 8 | mono?: boolean; 9 | }; 10 | 11 | const style = ({ gray = false, bold = false, mono = false }: LabelProps) => 12 | css({ 13 | fontWeight: bold ? "bold" : "regular", 14 | color: gray ? "gray" : "black", 15 | fontFamily: mono ? "mono" : "sans", 16 | lineHeight: "min", 17 | fontSize: 1, 18 | pointerEvents: "none", 19 | userSelect: "none", 20 | verticalAlign: "middle", 21 | display: "flex", 22 | alignItems: "center", 23 | width: "100%", 24 | } as SystemStyleObject); 25 | 26 | export const Label = styled.label>( 27 | style, 28 | ...commonStyle 29 | ); 30 | 31 | Label.displayName = "Label"; 32 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /src/StatelessToggleSwitchField.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { Box } from "./Box"; 3 | import { Col } from "./Col"; 4 | import { ToggleSwitch } from "./ToggleSwitch"; 5 | import { StructureProps } from "./system/unions"; 6 | 7 | export type StatelessToggleSwitchFieldProps = { 8 | selected?: boolean; 9 | hasError?: boolean; 10 | disabled?: boolean; 11 | } & React.HTMLAttributes & 12 | StructureProps; 13 | 14 | export const StatelessToggleSwitchField = ({ 15 | selected, 16 | disabled, 17 | hasError, 18 | onChange, 19 | children, 20 | ...props 21 | }: StatelessToggleSwitchFieldProps) => { 22 | return ( 23 | 24 | 30 | {children} 31 | 32 | ); 33 | }; 34 | 35 | StatelessToggleSwitchField.displayName = "StatelessToggleSwitchField"; 36 | -------------------------------------------------------------------------------- /docs/src/components/SidebarLink.tsx: -------------------------------------------------------------------------------- 1 | import { Link } from "react-router-dom"; 2 | import styled from "styled-components"; 3 | import css, { SystemStyleObject } from "@styled-system/css"; 4 | import { commonStyle, CommonStyleProps } from "local-indigo-react"; 5 | 6 | export type SidebarLinkProps = CommonStyleProps & { 7 | disabled?: boolean; 8 | destructive?: boolean; 9 | }; 10 | const style = () => 11 | css({ 12 | width: "auto", 13 | border: "none", 14 | overflow: "hidden", 15 | minHeight: 5, 16 | display: "flex", 17 | alignItems: "center", 18 | fontFamily: "sans", 19 | color: "gray", 20 | fontSize: 1, 21 | textDecoration: "none", 22 | borderRight: "1px solid", 23 | borderRightColor: "lightGray", 24 | "&:hover": { 25 | backgroundColor: "blue", 26 | borderRightColor: "blue", 27 | color: "white", 28 | }, 29 | } as SystemStyleObject); 30 | 31 | export const SidebarLink = styled(Link)< 32 | React.PropsWithChildren 33 | >(style, ...commonStyle); 34 | -------------------------------------------------------------------------------- /src/StatelessRadioButtonField.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { RadioButton } from "./RadioButton"; 3 | import { Box } from "./Box"; 4 | import { Col } from "./Col"; 5 | import { StructureProps } from "./system/unions"; 6 | 7 | export type StatelessRadioButtonFieldProps = { 8 | selected?: boolean; 9 | hasError?: boolean; 10 | disabled?: boolean; 11 | name: string; 12 | } & React.HTMLAttributes & 13 | StructureProps; 14 | 15 | export const StatelessRadioButtonField = ({ 16 | selected, 17 | disabled, 18 | hasError, 19 | onChange, 20 | children, 21 | name, 22 | ...props 23 | }: StatelessRadioButtonFieldProps) => { 24 | return ( 25 | 26 | 33 | {children} 34 | 35 | ); 36 | }; 37 | 38 | StatelessRadioButtonField.displayName = "StatelessRadioButtonField"; 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2020 Urbit 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /examples/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "parcel ./public/index.html NODE_ENV='development'", 9 | "tsc": "tsc -noEmit", 10 | "reset": "rm -rf node_modules package-lock.json && npm install" 11 | }, 12 | "alias": { 13 | "styled-components": "../node_modules/styled-components", 14 | "styled-system": "../node_modules/styled-system", 15 | "@styled-system/css": "../node_modules/@styled-system/css", 16 | "formik": "../node_modules/formik", 17 | "react": "../node_modules/react" 18 | }, 19 | "author": "Gavin Atkinson", 20 | "license": "MIT", 21 | "devDependencies": { 22 | "@types/react-dom": "^16.9.8", 23 | "@types/yup": "^0.29.5", 24 | "parcel": "^1.12.4", 25 | "typescript": "^3.9.7" 26 | }, 27 | "dependencies": { 28 | "@tlon/indigo-light": "^1.0.7", 29 | "local-indigo-react": "file:..", 30 | "react-dom": "^16.13.1", 31 | "styled-components": "^5.1.1", 32 | "styled-system": "^5.1.5", 33 | "yup": "^0.29.3" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/MenuItem.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import { 3 | MenuItem as ReachMenuItem, 4 | MenuItemProps as ReachMenuItemProps, 5 | } from "@reach/menu-button"; 6 | import css, { SystemStyleObject } from "@styled-system/css"; 7 | import { CommonStyleProps, commonStyle } from "./system/unions"; 8 | 9 | export type MenuItemProps = ReachMenuItemProps & CommonStyleProps; 10 | 11 | const style = () => 12 | css({ 13 | cursor: "pointer", 14 | textDecoration: "initial", 15 | display: "flex", 16 | alignItems: "center", 17 | px: 4, 18 | fontFamily: "sans", 19 | height: "24px", 20 | backgroundColor: "white", 21 | borderLeft: "1px solid", 22 | borderLeftColor: "lightGray", 23 | borderRight: "1px solid", 24 | borderRightColor: "lightGray", 25 | color: "black", 26 | "&:hover": { 27 | backgroundColor: "blue", 28 | color: "white", 29 | borderLeftColor: "blue", 30 | borderRightColor: "blue", 31 | outline: "none", 32 | }, 33 | } as SystemStyleObject); 34 | 35 | export const MenuItem = styled(ReachMenuItem)< 36 | React.PropsWithChildren 37 | >(style, ...commonStyle); 38 | 39 | export default MenuItem; 40 | -------------------------------------------------------------------------------- /src/ContinuousProgressBar.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import styled from "styled-components"; 3 | import css, { SystemStyleObject } from "@styled-system/css"; 4 | import { CommonStyleProps, commonStyle } from "./system/unions"; 5 | 6 | export type ContinuousProgressBarProps = CommonStyleProps & { 7 | percentage?: number; 8 | }; 9 | 10 | const style = ({ percentage = 0 }: ContinuousProgressBarProps) => 11 | css({ 12 | display: "flex", 13 | width: "100%", 14 | height: 1, 15 | position: "relative", 16 | backgroundColor: "lightGray", 17 | borderRadius: 3, 18 | overflow: "hidden", 19 | "&::before": { 20 | width: percentage + "%", 21 | backgroundColor: "blue", 22 | position: "absolute", 23 | top: 0, 24 | left: 0, 25 | content: "' '", 26 | height: "100%", 27 | borderRight: "1px solid", 28 | borderRightColor: percentage < 1 ? "transparent" : "white", 29 | transition: "width 200ms", 30 | }, 31 | } as SystemStyleObject); 32 | 33 | export const ContinuousProgressBar = styled.div< 34 | React.PropsWithChildren 35 | >(style, ...commonStyle); 36 | 37 | ContinuousProgressBar.displayName = "ContinuousProgressBar"; 38 | -------------------------------------------------------------------------------- /src/Icon.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import css, { SystemStyleObject } from "@styled-system/css"; 3 | import styled from "styled-components"; 4 | import { iconIndex } from "./iconIndex"; 5 | import { commonStyle, CommonStyleProps } from "./system/unions"; 6 | 7 | export type IconIndex = typeof iconIndex; 8 | 9 | export type IconProps = React.SVGProps & 10 | CommonStyleProps & { stroke?: string }; 11 | 12 | const SVG: React.FunctionComponent = styled.svg( 13 | ({ color }: IconProps) => 14 | css({ 15 | "& > *": { 16 | fill: typeof color === "undefined" ? "inherit" : color || "black", 17 | // REMOVE 18 | // stroke: typeof stroke === "undefined" ? "inherit" : stroke || "black", 19 | }, 20 | width: 3, 21 | height: 3, 22 | flexShrink: 0, 23 | } as SystemStyleObject), 24 | ...commonStyle 25 | ); 26 | 27 | export const Icon = ({ 28 | icon, 29 | ...props 30 | }: IconProps & { icon: keyof IconIndex }) => { 31 | const InnerIcon = iconIndex[icon] || iconIndex.NullIcon; 32 | 33 | return ( 34 | 35 | 36 | 37 | ); 38 | }; 39 | 40 | Icon.displayName = "Icon"; 41 | -------------------------------------------------------------------------------- /src/BackgroundImage.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import css, { SystemStyleObject } from "@styled-system/css"; 3 | import { 4 | border, 5 | BorderProps, 6 | color, 7 | ColorProps, 8 | flexbox, 9 | FlexboxProps, 10 | layout, 11 | LayoutProps, 12 | space, 13 | SpaceProps, 14 | position, 15 | PositionProps, 16 | background, 17 | BackgroundProps, 18 | } from "styled-system"; 19 | 20 | export type BackgroundImageProps = BorderProps & 21 | ColorProps & 22 | FlexboxProps & 23 | LayoutProps & 24 | SpaceProps & 25 | PositionProps & 26 | BackgroundProps & { 27 | src?: string; 28 | }; 29 | 30 | const style = ({ src }: BackgroundImageProps) => 31 | css({ 32 | backgroundPosition: "center", 33 | backgroundRepeat: "no-repeat", 34 | backgroundSize: "cover", 35 | width: "100%", 36 | height: "100%", 37 | backgroundImage: `url(${src})`, 38 | } as SystemStyleObject); 39 | 40 | const styleProps = [ 41 | border, 42 | color, 43 | flexbox, 44 | layout, 45 | space, 46 | background, 47 | position, 48 | ]; 49 | 50 | export const BackgroundImage = styled.div< 51 | React.PropsWithChildren 52 | >(style, ...styleProps); 53 | 54 | BackgroundImage.displayName = "BackgroundImage"; 55 | -------------------------------------------------------------------------------- /src/DisclosureButton.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import styled from "styled-components"; 3 | import css, { SystemStyleObject } from "@styled-system/css"; 4 | import { CommonStyleProps, commonStyle } from "./system/unions"; 5 | import { Icon } from "./Icon"; 6 | 7 | type DisclosureButtonWrapperProps = CommonStyleProps & { 8 | isOpen?: boolean; 9 | }; 10 | 11 | const style = () => 12 | css({ 13 | width: "100%", 14 | height: 5, 15 | borderRadius: 2, 16 | overflow: "hidden", 17 | display: "flex", 18 | alignItems: "center", 19 | px: "2", 20 | border: "1px solid", 21 | borderColor: "transparent", 22 | } as SystemStyleObject); 23 | 24 | const DisclosureButtonWrapper = styled.button< 25 | React.PropsWithChildren 26 | >(style, ...commonStyle); 27 | 28 | export type DisclosureButtonProps = DisclosureButtonWrapperProps & 29 | React.HTMLAttributes; 30 | 31 | export const DisclosureButton = ({ 32 | isOpen, 33 | children, 34 | ...props 35 | }: DisclosureButtonProps) => ( 36 | 37 | 38 | {children} 39 | 40 | ); 41 | 42 | DisclosureButton.displayName = "DisclosureButton"; 43 | -------------------------------------------------------------------------------- /src/StatelessTextArea.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import styled from "styled-components"; 3 | import css, { SystemStyleObject } from "@styled-system/css"; 4 | import { textInput } from "./system/tokens"; 5 | import { CommonStyleProps, commonStyle } from "./system/unions"; 6 | 7 | export type StatelessTextAreaProps = CommonStyleProps & { 8 | hasError?: boolean; 9 | disabled?: boolean; 10 | } & React.HTMLAttributes; 11 | 12 | const stateStyle = (hasError: boolean, disabled: boolean) => { 13 | if (hasError) return textInput.state.hasError; 14 | if (disabled) return textInput.state.disabled; 15 | return textInput.state.default; 16 | }; 17 | 18 | const style = ({ 19 | hasError = false, 20 | disabled = false, 21 | }: StatelessTextAreaProps) => 22 | css({ 23 | boxSizing: "border-box", 24 | width: "100%", 25 | p: 2, 26 | border: "1px solid", 27 | borderRadius: 2, 28 | resize: "vertical", 29 | minHeight: 5, 30 | ...textInput.text, 31 | ...stateStyle(hasError, disabled), 32 | } as SystemStyleObject); 33 | 34 | export const StatelessTextArea = styled.textarea< 35 | React.PropsWithChildren 36 | >(style, ...commonStyle); 37 | 38 | StatelessTextArea.defaultProps = { 39 | cols: 8, 40 | }; 41 | 42 | StatelessTextArea.displayName = "StatelessTextArea"; 43 | -------------------------------------------------------------------------------- /src/StatelessTextInput.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import styled from "styled-components"; 3 | import css, { SystemStyleObject } from "@styled-system/css"; 4 | import { textInput } from "./system/tokens"; 5 | import { CommonStyleProps, commonStyle } from "./system/unions"; 6 | 7 | export type StatelessTextInputProps = CommonStyleProps & { 8 | hasError?: boolean; 9 | disabled?: boolean; 10 | } & React.HTMLAttributes; 11 | 12 | const stateStyle = (hasError: boolean, disabled: boolean) => { 13 | if (hasError) return textInput.state.hasError; 14 | if (disabled) return textInput.state.disabled; 15 | return textInput.state.default; 16 | }; 17 | 18 | const style = ({ 19 | hasError = false, 20 | disabled = false, 21 | }: StatelessTextInputProps) => 22 | css({ 23 | boxSizing: "border-box", 24 | width: "100%", 25 | height: 5, 26 | px: 2, 27 | display: "flex", 28 | alignItems: "center", 29 | border: "1px solid", 30 | borderRadius: 2, 31 | ...textInput.text, 32 | ...stateStyle(hasError, disabled), 33 | } as SystemStyleObject); 34 | 35 | export const StatelessTextInput = styled.input< 36 | React.PropsWithChildren 37 | >(style, ...commonStyle); 38 | 39 | StatelessTextInput.defaultProps = { 40 | type: "text", 41 | }; 42 | 43 | StatelessTextInput.displayName = "TextInput"; 44 | -------------------------------------------------------------------------------- /docs/src/components/IndigoIcon.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { BaseSVG } from "local-indigo-react"; 3 | 4 | export const IndigoIcon = (props) => ( 5 | 13 | 14 | 20 | 26 | 32 | 33 | ); 34 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | // Signifies which target of JavaScript should be emitted? 4 | "target": "ES2015", 5 | // What module format should be emitted? 6 | "module": "ES2015", 7 | // See: https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Module%20Resolution.md 8 | "moduleResolution": "node", 9 | // Output destination 10 | "outDir": "dist", 11 | // This lib uses JSX, so support it 12 | "jsx": "react", 13 | // Allow default imports from modules with no default export. This does not affect code emit, just typechecking. 14 | "esModuleInterop": true, 15 | // Don't typecheck libraries in node_modules 16 | "skipLibCheck": true, 17 | // Export type declarations and only type declrations. No extra source files to dist. 18 | "emitDeclarationOnly": true, 19 | "declaration": true, 20 | // Enables --noImplicitAny, --dnoImplicitThis, --alwaysStrict, --strictBindCallApply, --strictNullChecks, --strictFunctionTypes and --strictPropertyInitialization. 21 | "strict": true, 22 | // Minor style enforcements 23 | "noImplicitReturns": true, 24 | "noFallthroughCasesInSwitch": true, 25 | // The following can be set to false in development to make prototyping easier. 26 | "noUnusedLocals": true, 27 | "noUnusedParameters": true 28 | }, 29 | "files": ["src/index.tsx"] 30 | } 31 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "indigo-docs", 3 | "version": "1.0.0", 4 | "description": "Documentation site for Indigo", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "parcel ./public/index.html NODE_ENV='development'", 9 | "tsc": "tsc -noEmit", 10 | "reset": "rm -rf node_modules package-lock.json && npm install" 11 | }, 12 | "alias": { 13 | "styled-components": "../node_modules/styled-components", 14 | "styled-system": "../node_modules/styled-system", 15 | "@styled-system/css": "../node_modules/@styled-system/css", 16 | "formik": "../node_modules/formik", 17 | "react": "../node_modules/react" 18 | }, 19 | "author": "Gavin Atkinson", 20 | "license": "MIT", 21 | "devDependencies": { 22 | "@types/react-dom": "^16.9.8", 23 | "@types/yup": "^0.29.5", 24 | "parcel": "^1.12.4", 25 | "parcel-plugin-static-files-copy": "^2.5.0", 26 | "typescript": "^3.9.7" 27 | }, 28 | "dependencies": { 29 | "@tlon/indigo-light": "^1.0.4", 30 | "@types/react-router-dom": "^5.1.5", 31 | "local-indigo-react": "file:..", 32 | "react-dom": "^16.13.1", 33 | "react-live": "^2.2.2", 34 | "react-router-dom": "^5.2.0", 35 | "yup": "^0.29.3" 36 | }, 37 | "staticFiles": { 38 | "staticPath": "public", 39 | "watcherGlob": "**" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /docs/src/pages/ComponentPage.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { useState, useEffect } from "react"; 3 | import { useParams, Link } from "react-router-dom"; 4 | import { Col, Text } from "local-indigo-react"; 5 | import { baseURL } from "../constants"; 6 | import { ComponentPreview } from "../components/ComponentPreview"; 7 | import { ComponentProperties } from "../types"; 8 | 9 | const fetchProperties = (id: string) => { 10 | return fetch(`${baseURL}/componentData/${id}.json`) 11 | .then((response) => response.json()) 12 | .catch((err) => console.error(err)); 13 | }; 14 | 15 | const fetchComponentData = (id: string) => { 16 | return Promise.resolve(fetchProperties(id)).then( 17 | (properties: ComponentProperties) => { 18 | return properties; 19 | } 20 | ); 21 | }; 22 | 23 | export const ComponentPage = () => { 24 | let { id } = useParams(); 25 | 26 | const promise = fetchComponentData(id); 27 | 28 | const [properties, setProperties] = useState(); 29 | 30 | useEffect(() => { 31 | promise.then((properties) => setProperties(properties)); 32 | }, []); 33 | 34 | if (properties?.displayName) { 35 | return ( 36 | 37 | {"<- Index"} 38 | {properties.displayName} 39 | 40 | 41 | ); 42 | } else { 43 | return Loading...; 44 | } 45 | }; 46 | -------------------------------------------------------------------------------- /src/Indicator.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import styled from "styled-components"; 3 | import css, { SystemStyleObject } from "@styled-system/css"; 4 | 5 | import { indicator } from "./system/tokens"; 6 | import { commonStyle, CommonStyleProps } from "./system/unions"; 7 | 8 | export type IndicatorProps = CommonStyleProps & { 9 | disabled?: boolean; 10 | selected?: boolean; 11 | hasError?: boolean; 12 | }; 13 | 14 | const stateStyle = ( 15 | disabled: boolean, 16 | hasError: boolean, 17 | selected: boolean 18 | ) => { 19 | if (selected && disabled) return indicator.state.onDisabled; 20 | if (selected && hasError) return indicator.state.onError; 21 | if (selected) return indicator.state.on; 22 | if (disabled) return indicator.state.offDisabled; 23 | if (hasError) return indicator.state.offError; 24 | return indicator.state.off; 25 | }; 26 | 27 | const style = ({ 28 | disabled = false, 29 | hasError = false, 30 | selected = false, 31 | }: IndicatorProps) => 32 | css({ 33 | width: 3, 34 | border: "1px solid", 35 | height: 3, 36 | borderRadius: 2, 37 | cursor: "pointer", 38 | "& > *": { 39 | transform: "translate(-1px,-1px)", 40 | }, 41 | ...stateStyle(disabled, hasError, selected), 42 | } as SystemStyleObject); 43 | 44 | export const Indicator = styled.div>( 45 | style, 46 | ...commonStyle 47 | ); 48 | 49 | Indicator.displayName = "Indicator"; 50 | -------------------------------------------------------------------------------- /src/TwoUp.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { ResponsiveValue, ThemeValue, RequiredTheme } from "styled-system"; 3 | import { AllSystemProps } from "./system/unions"; 4 | import { Col } from "./Col"; 5 | import { Box } from "./Box"; 6 | 7 | export type TwoUpProps = AllSystemProps & 8 | React.HTMLAttributes & { 9 | children: React.ReactNodeArray; 10 | gapX: ResponsiveValue>; 11 | gapY: ResponsiveValue>; 12 | gap: ResponsiveValue>; 13 | }; 14 | 15 | const cells = [ 16 | { 17 | gridColumn: ["1 / 2", "1 / 2"], 18 | gridRow: ["1 / 2", "1 / 2"], 19 | }, 20 | { 21 | gridColumn: ["1 / 2", "2 / 3"], 22 | gridRow: ["2 / 3", "1 / 2"], 23 | }, 24 | ]; 25 | 26 | export const TwoUp = ({ 27 | children, 28 | gap = 0, 29 | gapX, 30 | gapY, 31 | ...props 32 | }: TwoUpProps) => { 33 | const twoChildren = children.slice(0, 2) as React.ReactNodeArray; 34 | 35 | return ( 36 | // @ts-ignore 37 | 45 | {twoChildren.map((child, index) => ( 46 | {child} 47 | ))} 48 | 49 | ); 50 | }; 51 | 52 | TwoUp.displayName = "TwoUp"; 53 | -------------------------------------------------------------------------------- /src/Action.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import css, { SystemStyleObject } from "@styled-system/css"; 3 | import { commonStyle, CommonStyleProps } from "./system/unions"; 4 | import { action } from "./system/tokens"; 5 | 6 | export type ActionProps = CommonStyleProps & { 7 | disabled?: boolean; 8 | destructive?: boolean; 9 | hideDisabled?: boolean; 10 | }; 11 | 12 | const stateColor = ( 13 | destructive: boolean, 14 | disabled: boolean, 15 | hideDisabled: boolean 16 | ) => { 17 | if (hideDisabled) { 18 | disabled = false; 19 | } 20 | if (destructive && disabled) return action.state.destructiveDisabled; 21 | if (destructive) return action.state.destructive; 22 | if (disabled) return action.state.defaultDisabled; 23 | return action.state.default; 24 | }; 25 | 26 | const style = ({ 27 | destructive = false, 28 | disabled = false, 29 | hideDisabled = false, 30 | }: ActionProps) => 31 | css({ 32 | width: "auto", 33 | border: "none", 34 | overflow: "hidden", 35 | height: 3, 36 | backgroundColor: "white", 37 | ...action.text, 38 | ...stateColor(destructive, disabled, hideDisabled), 39 | } as SystemStyleObject); 40 | 41 | export const Action = styled.button>( 42 | style, 43 | ...commonStyle 44 | ); 45 | 46 | export const asAction = (component: React.FC) => 47 | styled(component)>( 48 | style, 49 | ...commonStyle 50 | ); 51 | 52 | Action.displayName = "Action"; 53 | -------------------------------------------------------------------------------- /src/ToggleSwitch.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import styled from "styled-components"; 3 | import css, { SystemStyleObject } from "@styled-system/css"; 4 | import { toggleSwitch } from "./system/tokens"; 5 | import { StructureProps, structureStyle } from "./system/unions"; 6 | 7 | export type ToggleSwitchProps = StructureProps & { 8 | selected?: boolean; 9 | hasError?: boolean; 10 | disabled?: boolean; 11 | } & React.HTMLAttributes; 12 | 13 | const stateStyle = ( 14 | selected: boolean, 15 | hasError: boolean, 16 | disabled: boolean 17 | ) => { 18 | if (selected && disabled) return toggleSwitch.states.selectedDisabled; 19 | if (hasError && selected) return toggleSwitch.states.hasErrorSelected; 20 | if (hasError) return toggleSwitch.states.hasError; 21 | if (disabled) return toggleSwitch.states.disabled; 22 | if (selected) return toggleSwitch.states.selected; 23 | return toggleSwitch.states.default; 24 | }; 25 | 26 | const style = ({ 27 | selected = false, 28 | hasError = false, 29 | disabled = false, 30 | }: ToggleSwitchProps) => 31 | css({ 32 | position: "relative", 33 | width: "24px", 34 | flexShrink: "0", 35 | height: "16px", 36 | border: "1px solid", 37 | borderRadius: "999px", 38 | cursor: "pointer", 39 | ...stateStyle(selected, hasError, disabled), 40 | } as SystemStyleObject); 41 | 42 | export const ToggleSwitch = styled.div< 43 | React.PropsWithChildren 44 | >(style, ...structureStyle); 45 | 46 | ToggleSwitch.displayName = "ToggleSwitch"; 47 | -------------------------------------------------------------------------------- /src/MenuList.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import styled from "styled-components"; 3 | import { 4 | MenuList as ReachMenuList, 5 | MenuListProps as ReachMenuListProps, 6 | } from "@reach/menu-button"; 7 | import css, { SystemStyleObject } from "@styled-system/css"; 8 | import { CommonStyleProps, commonStyle } from "./system/unions"; 9 | 10 | export type MenuListProps = ReachMenuListProps & CommonStyleProps; 11 | 12 | const style = () => 13 | css({ 14 | // width: "200px", 15 | padding: 0, 16 | outline: "none", 17 | mt: "1px", 18 | py: 2, 19 | border: "none", 20 | backgroundColor: "white", 21 | borderRadius: 2, 22 | } as SystemStyleObject); 23 | 24 | const MenuListWrapper = styled(ReachMenuList)< 25 | React.PropsWithChildren 26 | >(style, ...commonStyle); 27 | 28 | const MenuListTopCap = styled.div(() => 29 | css({ 30 | height: 2, 31 | width: "100%", 32 | borderTopLeftRadius: 2, 33 | borderTopRightRadius: 2, 34 | border: "1px solid", 35 | borderBottom: "none", 36 | borderColor: "lightGray", 37 | } as SystemStyleObject) 38 | ); 39 | 40 | const MenListBottomCap = styled.div(() => 41 | css({ 42 | height: 2, 43 | width: "100%", 44 | borderBottomLeftRadius: 2, 45 | borderBottomRightRadius: 2, 46 | border: "1px solid", 47 | borderTop: "none", 48 | borderColor: "lightGray", 49 | } as SystemStyleObject) 50 | ); 51 | 52 | export const MenuList = ({ children }: MenuListProps) => ( 53 | 54 | 55 | {children} 56 | 57 | 58 | ); 59 | -------------------------------------------------------------------------------- /src/Anchor.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import css, { SystemStyleObject } from "@styled-system/css"; 3 | import { 4 | color, 5 | ColorProps, 6 | layout, 7 | LayoutProps, 8 | space, 9 | SpaceProps, 10 | typography, 11 | TypographyProps, 12 | BorderProps, 13 | border, 14 | FlexboxProps, 15 | flexbox, 16 | } from "styled-system"; 17 | 18 | export type AnchorProps = BorderProps & 19 | FlexboxProps & 20 | ColorProps & 21 | LayoutProps & 22 | SpaceProps & 23 | TypographyProps & { 24 | gray?: boolean; 25 | bold?: boolean; 26 | mono?: boolean; 27 | underline?: boolean; 28 | textDecoration?: string; 29 | }; 30 | 31 | const style = ({ 32 | color, 33 | gray = false, 34 | bold = false, 35 | mono = false, 36 | underline = true, 37 | }: AnchorProps) => 38 | css({ 39 | cursor: "pointer", 40 | display: "inline-block", 41 | textDecoration: underline ? "underline" : "none", 42 | fontWeight: bold ? "bold" : "regular", 43 | color: gray ? "gray" : "black", 44 | fontFamily: mono ? "mono" : "sans", 45 | lineHeight: "short", 46 | fontSize: 1, 47 | "&:visited": { 48 | color: color || gray ? "gray" : "black", 49 | }, 50 | } as SystemStyleObject); 51 | 52 | const styleProps = [border, color, flexbox, layout, space, typography]; 53 | 54 | export const Anchor = styled.a>( 55 | style, 56 | ...styleProps 57 | ); 58 | 59 | export const asAnchor = (component: React.FC) => 60 | styled(component)>(style, ...styleProps); 61 | 62 | Anchor.displayName = "Anchor"; 63 | -------------------------------------------------------------------------------- /src/FourUp.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { ResponsiveValue, ThemeValue, RequiredTheme } from "styled-system"; 3 | import { AllSystemProps } from "./system/unions"; 4 | import { Col } from "./Col"; 5 | import { Box } from "./Box"; 6 | 7 | export type FourUpProps = AllSystemProps & 8 | React.HTMLAttributes & { 9 | children: React.ReactNodeArray; 10 | gx: ResponsiveValue>; 11 | gy: ResponsiveValue>; 12 | gap: ResponsiveValue>; 13 | }; 14 | 15 | const cells = [ 16 | { 17 | gridColumn: ["1 / 2", "1 / 2", "1 / 2"], 18 | gridRow: ["1 / 3", "1 / 2", "1 / 2"], 19 | }, 20 | { 21 | gridColumn: ["1 / 2", "2 / 3", "2 / 3"], 22 | gridRow: ["2 / 3", "1 / 2", "1 / 2"], 23 | }, 24 | { 25 | gridColumn: ["1 / 2", "1 / 2", "3 / 4"], 26 | gridRow: ["3 / 5", "2 / 3", "1 / 2"], 27 | }, 28 | { 29 | gridColumn: ["1 / 2", "2 / 3", "4 / 5"], 30 | gridRow: ["4 / 5", "2 / 3", "1 / 2"], 31 | }, 32 | ]; 33 | 34 | export const FourUp = ({ 35 | children, 36 | gap = 0, 37 | gx, 38 | gy, 39 | ...props 40 | }: FourUpProps) => { 41 | const fourChildren = children.slice(0, 4) as React.ReactNodeArray; 42 | 43 | return ( 44 | // @ts-ignore 45 | 53 | {fourChildren.map((child, index) => ( 54 | {child} 55 | ))} 56 | 57 | ); 58 | }; 59 | 60 | FourUp.displayName = "FourUp"; 61 | -------------------------------------------------------------------------------- /src/ManagedTextAreaField.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { useField } from "formik"; 3 | import { Box, StatelessTextArea, ErrorLabel, Label } from "./index"; 4 | 5 | import { CommonStyleProps } from "./system/unions"; 6 | 7 | export type ManagedTextAreaFieldProps = { 8 | hasError?: boolean; 9 | disabled?: boolean; 10 | placeholder?: string; 11 | id: string; 12 | label?: string; 13 | caption?: string; 14 | type?: string; 15 | autoFocus?: boolean; 16 | } & React.HTMLAttributes & 17 | React.HTMLAttributes & 18 | CommonStyleProps; 19 | 20 | export const ManagedTextAreaField = ({ 21 | disabled, 22 | hasError, 23 | placeholder, 24 | label, 25 | caption, 26 | id, 27 | children, 28 | type, 29 | fontFamily, 30 | borderColor, 31 | color, 32 | fontWeight, 33 | autoFocus, 34 | ...props 35 | }: ManagedTextAreaFieldProps) => { 36 | const [field, meta] = useField(id); 37 | 38 | return ( 39 | 40 | 41 | {caption ? ( 42 | 45 | ) : null} 46 | 58 | 59 | {meta.error} 60 | 61 | 62 | ); 63 | }; 64 | 65 | ManagedTextAreaField.displayName = "ManagedTextAreaField"; 66 | -------------------------------------------------------------------------------- /src/ManagedToggleSwitchField.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import styled from "styled-components"; 3 | import { useField } from "formik"; 4 | import { ToggleSwitch, BaseLabel, Label, ErrorLabel, Box, Col } from "./index"; 5 | import { StructureProps } from "./system/unions"; 6 | 7 | type ManagedToggleSwitchFieldProps = StructureProps & { 8 | caption?: string; 9 | label: string; 10 | id: string; 11 | disabled?: boolean; 12 | }; 13 | 14 | // Hide this input completely 15 | const HiddenInput = styled.input` 16 | position: absolute; 17 | opacity: 0; 18 | height: 0; 19 | width: 0; 20 | margin: 0px; 21 | `; 22 | 23 | export const ManagedToggleSwitchField = ({ 24 | label, 25 | caption, 26 | id, 27 | disabled, 28 | ...props 29 | }: ManagedToggleSwitchFieldProps) => { 30 | const [field, meta] = useField({ name: id, type: "checkbox" }); 31 | return ( 32 | 33 | 39 | 45 | 46 | 47 | {caption ? ( 48 | 51 | ) : null} 52 | 60 | 61 | {meta.error} 62 | 63 | 64 | 65 | 66 | ); 67 | }; 68 | -------------------------------------------------------------------------------- /src/SegmentedProgressBar.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import styled from "styled-components"; 3 | import css, { SystemStyleObject } from "@styled-system/css"; 4 | import { CommonStyleProps, commonStyle } from "./system/unions"; 5 | import { sequence } from "./util"; 6 | 7 | export type ContinuousProgressBarProps = CommonStyleProps & { 8 | percentage?: number; 9 | }; 10 | 11 | type SegmentProps = { 12 | active: boolean; 13 | }; 14 | 15 | const segmentStyle = ({ active }: SegmentProps) => 16 | css({ 17 | flexGrow: 1, 18 | backgroundColor: active ? "blue" : "transparent", 19 | content: "' '", 20 | height: "100%", 21 | borderRight: "1px solid", 22 | borderRightColor: "white", 23 | } as SystemStyleObject); 24 | 25 | const Segment = styled.div>(segmentStyle); 26 | 27 | const backgroundStyle = () => 28 | css({ 29 | display: "flex", 30 | width: "100%", 31 | height: 1, 32 | backgroundColor: "lightGray", 33 | borderRadius: 3, 34 | overflow: "hidden", 35 | "& :last-child": { 36 | borderRightColor: "transparent", 37 | }, 38 | } as SystemStyleObject); 39 | 40 | const Background = styled.div>( 41 | backgroundStyle, 42 | ...commonStyle 43 | ); 44 | 45 | export type SegmentedProgressBarProps = { 46 | segments?: number; 47 | current?: number; 48 | }; 49 | 50 | export const SegmentedProgressBar = ({ 51 | segments = 1, 52 | current = 0, 53 | ...props 54 | }: SegmentedProgressBarProps) => { 55 | return ( 56 | 57 | {sequence(segments).map((_, index: number) => ( 58 | 59 | ))} 60 | 61 | ); 62 | }; 63 | 64 | Background.displayName = "Background"; 65 | Segment.displayName = "Segment"; 66 | SegmentedProgressBar.displayName = "SegmentedProgressBar"; 67 | -------------------------------------------------------------------------------- /src/MenuButton.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import styled from "styled-components"; 3 | import { 4 | MenuButton as ReachMenuButton, 5 | MenuButtonProps as ReachMenuButtonProps, 6 | } from "@reach/menu-button"; 7 | 8 | import css, { SystemStyleObject } from "@styled-system/css"; 9 | import { container, button } from "./system/tokens"; 10 | import { CommonStyleProps, commonStyle } from "./system/unions"; 11 | 12 | export type MenuButtonProps = ReachMenuButtonProps & 13 | CommonStyleProps & { 14 | primary?: boolean; 15 | disabled?: boolean; 16 | destructive?: boolean; 17 | }; 18 | 19 | const stateStyle = ( 20 | primary: boolean, 21 | destructive: boolean, 22 | disabled: boolean 23 | ) => { 24 | if (destructive && primary && disabled) 25 | return button.state.destructivePrimaryDisabled; 26 | if (primary && disabled) return button.state.primaryDisabled; 27 | if (destructive && disabled) return button.state.destructiveDisabled; 28 | if (destructive && primary) return button.state.destructivePrimary; 29 | if (destructive) return button.state.destructive; 30 | if (primary) return button.state.primary; 31 | if (disabled) return button.state.defaultDisabled; 32 | return button.state.default; 33 | }; 34 | 35 | const style = ({ 36 | primary = false, 37 | destructive = false, 38 | disabled = false, 39 | }: MenuButtonProps) => 40 | css({ 41 | width: "100%", 42 | justifyContent: "space-between", 43 | border: "1px solid", 44 | height: 5, 45 | borderRadius: 2, 46 | overflow: "hidden", 47 | px: 2, 48 | ...button.text, 49 | ...container.center, 50 | ...stateStyle(primary, destructive, disabled), 51 | } as SystemStyleObject); 52 | 53 | export const MenuButton = styled(ReachMenuButton)< 54 | React.PropsWithChildren 55 | >(style, ...commonStyle); 56 | 57 | MenuButton.displayName = "MenuButton"; 58 | 59 | export default MenuButton; 60 | -------------------------------------------------------------------------------- /src/ManagedTextInputField.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { useField } from "formik"; 3 | 4 | import { Box } from "./Box"; 5 | import { StatelessTextInput } from "./StatelessTextInput"; 6 | import { ErrorLabel } from "./ErrorLabel"; 7 | import { Label } from "./Label"; 8 | import { CommonStyleProps } from "./system/unions"; 9 | 10 | export type ManagedTextInputFieldProps = { 11 | hasError?: boolean; 12 | disabled?: boolean; 13 | placeholder?: string; 14 | id: string; 15 | label?: string; 16 | caption?: string; 17 | type?: string; 18 | autoFocus?: boolean; 19 | } & React.HTMLAttributes & 20 | React.HTMLAttributes & 21 | CommonStyleProps; 22 | 23 | export const ManagedTextInputField = ({ 24 | disabled, 25 | hasError, 26 | placeholder, 27 | label, 28 | caption, 29 | id, 30 | children, 31 | type, 32 | fontFamily, 33 | borderColor, 34 | color, 35 | fontWeight, 36 | autoFocus, 37 | ...props 38 | }: ManagedTextInputFieldProps) => { 39 | const [field, meta] = useField(id); 40 | 41 | return ( 42 | 43 | 44 | {caption ? ( 45 | 48 | ) : null} 49 | 62 | 63 | {meta.error} 64 | 65 | 66 | ); 67 | }; 68 | 69 | ManagedTextInputField.displayName = "ManagedTextInputField"; 70 | -------------------------------------------------------------------------------- /scripts/generate_docs.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const path = require("path"); 3 | 4 | const src = __dirname + "/../src"; 5 | const out = __dirname + "/../docs/public/componentData"; 6 | const public = __dirname + "/../docs/public"; 7 | 8 | const include = [""]; 9 | const exclude = [ 10 | ".DS_Store", 11 | "util.ts", 12 | "index.tsx", 13 | "index.ts", 14 | "iconIndex.tsx", 15 | "themes", 16 | ]; 17 | 18 | const sourceFiles = fs 19 | .readdirSync(src) 20 | .map((sourcePath) => path.parse(sourcePath)) 21 | .filter((parsedPath) => !exclude.includes(parsedPath.base)) 22 | .filter((parsedPath) => include.includes(parsedPath.ext)); 23 | const basicDocjson = (name) => `{ 24 | "snippet": "<${name}> " 25 | }`; 26 | 27 | function lowercaseFirstLetter(string) { 28 | return string.charAt(0).toLowerCase() + string.slice(1); 29 | } 30 | 31 | sourceFiles.map((parsedPath) => { 32 | const componentExampleJs = fs.readFileSync( 33 | src + "/" + parsedPath.base + "/" + "docs.js", 34 | { encoding: "utf8" } 35 | ); 36 | const id = lowercaseFirstLetter(parsedPath.base); 37 | const displayName = parsedPath.base; 38 | const data = { 39 | id, 40 | displayName, 41 | snippet: componentExampleJs, 42 | props: [], 43 | }; 44 | 45 | fs.writeFileSync(out + "/" + id + ".json", JSON.stringify(data), "utf8"); 46 | }); 47 | 48 | // const stats = { 49 | // componentCount: sourceFiles.length 50 | // } 51 | // fs.writeFileSync(public + '/' + 'stats' + '.json', JSON.stringify(stats), "utf8"); 52 | 53 | const components = sourceFiles.map((parsedPath) => { 54 | const k = lowercaseFirstLetter(parsedPath.base); 55 | const displayName = parsedPath.base; 56 | return { 57 | id: k, 58 | displayName, 59 | }; 60 | }); 61 | 62 | const manifest = { 63 | componentCount: sourceFiles.length, 64 | components: components, 65 | }; 66 | 67 | fs.writeFileSync( 68 | public + "/" + "manifest" + ".json", 69 | JSON.stringify(manifest), 70 | "utf8" 71 | ); 72 | -------------------------------------------------------------------------------- /src/Button.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import styled from "styled-components"; 3 | import css, { SystemStyleObject } from "@styled-system/css"; 4 | import { container, button } from "./system/tokens"; 5 | import { CommonStyleProps, commonStyle } from "./system/unions"; 6 | 7 | export type ButtonProps = CommonStyleProps & { 8 | primary?: boolean; 9 | disabled?: boolean; 10 | destructive?: boolean; 11 | hideDisabled?: boolean; 12 | }; 13 | 14 | const stateStyle = ( 15 | primary: boolean, 16 | destructive: boolean, 17 | disabled: boolean, 18 | hideDisabled: boolean 19 | ) => { 20 | if(hideDisabled) { 21 | disabled = false; 22 | } 23 | if (destructive && primary && disabled) 24 | return button.state.destructivePrimaryDisabled; 25 | if (primary && disabled) return button.state.primaryDisabled; 26 | if (destructive && disabled) return button.state.destructiveDisabled; 27 | if (destructive && primary) return button.state.destructivePrimary; 28 | if (destructive) return button.state.destructive; 29 | if (primary) return button.state.primary; 30 | if (disabled) return button.state.defaultDisabled; 31 | return button.state.default; 32 | }; 33 | 34 | const style = ({ 35 | primary = false, 36 | destructive = false, 37 | disabled = false, 38 | hideDisabled = false 39 | }: ButtonProps) => 40 | css({ 41 | width: "auto", 42 | border: "1px solid", 43 | height: 5, 44 | borderRadius: 2, 45 | overflow: "hidden", 46 | px: 3, 47 | backgroundColor: "white", 48 | ...button.text, 49 | ...container.center, 50 | ...stateStyle(primary, destructive, disabled, hideDisabled), 51 | } as SystemStyleObject); 52 | 53 | export const Button = styled.button>( 54 | style, 55 | ...commonStyle 56 | ); 57 | 58 | export const asButton = (component: React.FC) => 59 | styled(component)>( 60 | style, 61 | ...commonStyle 62 | ); 63 | 64 | Button.displayName = "Button"; 65 | -------------------------------------------------------------------------------- /src/Reset.tsx: -------------------------------------------------------------------------------- 1 | import { createGlobalStyle } from "styled-components"; 2 | import { Theme } from "./themes/light"; 3 | 4 | // Used to set browser default css to new defaults to accomodate Indigo 5 | export const Reset = createGlobalStyle` 6 | html, body, div, span, applet, object, iframe, 7 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 8 | a, abbr, acronym, address, big, cite, code, 9 | del, dfn, em, img, ins, kbd, q, s, samp, 10 | small, strike, strong, sub, sup, tt, var, 11 | b, u, i, center, 12 | dl, dt, dd, ol, ul, li, 13 | fieldset, form, label, legend, 14 | table, caption, tbody, tfoot, thead, tr, th, td, 15 | article, aside, canvas, details, embed, 16 | figure, figcaption, footer, header, hgroup, 17 | menu, nav, output, ruby, section, summary, 18 | time, mark, audio, video { 19 | margin: 0; 20 | padding: 0; 21 | border: 0; 22 | font-size: 100%; 23 | font: inherit; 24 | vertical-align: baseline; 25 | box-sizing: border-box; 26 | font-weight: normal; 27 | } 28 | html, body { 29 | background-color: ${(p: { theme: Theme }) => p.theme.colors.white}; 30 | } 31 | 32 | * { 33 | -webkit-font-smoothing: antialiased; 34 | } 35 | 36 | ol, ul { 37 | list-style: none; 38 | } 39 | 40 | li { 41 | margin-left: 32px; 42 | } 43 | 44 | blockquote, q { 45 | quotes: none; 46 | } 47 | blockquote:before, blockquote:after, 48 | q:before, q:after { 49 | content: ''; 50 | content: none; 51 | } 52 | table { 53 | border-collapse: collapse; 54 | border-spacing: 0; 55 | } 56 | button { 57 | box-sizing: border-box; 58 | border: 0; 59 | outline: none; 60 | cursor: pointer; 61 | background-color: transparent; 62 | user-select: none; 63 | margin: 0px; 64 | padding: 0px; 65 | } 66 | 67 | button:disabled { 68 | cursor: default; 69 | } 70 | img { 71 | height: auto; 72 | width: 100%; 73 | } 74 | * { 75 | outline: none; 76 | } 77 | `; 78 | Reset.displayName = "CSSReset"; 79 | -------------------------------------------------------------------------------- /src/ManagedCheckboxField.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import styled from "styled-components"; 3 | import { useField } from "formik"; 4 | import { BaseLabel, Label, ErrorLabel, Checkbox, Box, Col } from "./index"; 5 | import { StructureProps } from "./system/unions"; 6 | 7 | type ManagedCheckboxFieldProps = StructureProps & { 8 | caption?: string; 9 | label: string; 10 | id: string; 11 | disabled?: boolean; 12 | }; 13 | 14 | // Hide this input completely 15 | const HiddenInput = styled.input` 16 | position: absolute; 17 | opacity: 0; 18 | height: 0; 19 | width: 0; 20 | margin: 0px; 21 | `; 22 | 23 | export const ManagedCheckboxField = ({ 24 | label, 25 | caption, 26 | id, 27 | disabled, 28 | ...props 29 | }: ManagedCheckboxFieldProps) => { 30 | const [field, meta, { setTouched }] = useField({ 31 | name: id, 32 | type: "checkbox", 33 | }); 34 | 35 | // Chrome and Safari do not send blur events properly 36 | const onChange = React.useCallback( 37 | (e: React.ChangeEvent) => { 38 | setTouched(true); 39 | field.onChange(e); 40 | }, 41 | [field.onChange, setTouched] 42 | ); 43 | 44 | return ( 45 | 46 | 52 | 58 | 59 | 60 | {caption ? ( 61 | 64 | ) : null} 65 | 74 | 75 | {meta.error} 76 | 77 | 78 | 79 | 80 | ); 81 | }; 82 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@tlon/indigo-react", 3 | "version": "1.2.27", 4 | "description": "React implementation of Tlon's design system, Indigo", 5 | "main": "dist/index.js", 6 | "types": "dist/index.d.ts", 7 | "scripts": { 8 | "test": "echo \"Error: no test specified\" && exit 1", 9 | "tsc": "tsc", 10 | "esbuild": "esbuild src/index.tsx --bundle --external:react --external:react-is --external:react-dom --external:styled-system --external:styled-components --external:@styled-system/css --external:formik --outdir=dist --format=esm --splitting --sourcemap", 11 | "esbuild:prod": "esbuild src/index.tsx --bundle --external:react --external:react-is --external:react-dom --external:styled-system --external:styled-components --external:@styled-system/css --external:formik --outdir=dist --format=esm --splitting --sourcemap", 12 | "clear": "rm -rf dist", 13 | "reset": "rm -rf node_modules package-lock.json && npm install", 14 | "build": "npm run tsc && npm run esbuild", 15 | "build:prod": "npm run tsc && npm run esbuild:prod", 16 | "format": "prettier --write ./src/*", 17 | "prepare": "npm run build" 18 | }, 19 | "author": "Gavin Atkinson", 20 | "license": "MIT", 21 | "dependencies": { 22 | "tslib": "^2.0.1" 23 | }, 24 | "peerDependencies": { 25 | "styled-components": "^5.1.1", 26 | "styled-system": "^5.1.5", 27 | "formik": "^2.1.5", 28 | "@reach/menu-button": "^0.17.0", 29 | "react": "^16.8 || ^17", 30 | "react-dom": "^16.8 || ^17" 31 | }, 32 | "devDependencies": { 33 | "@styled-system/css": "^5.1.5", 34 | "@tlon/indigo-light": "^1.0.3", 35 | "@types/react": "^16.9.46", 36 | "@types/styled-components": "^5.1.7", 37 | "@types/styled-system": "^5.1.10", 38 | "@types/styled-system__css": "^5.0.14", 39 | "esbuild": "^0.6.28", 40 | "formik": "^2.1.5", 41 | "husky": "^4.2.5", 42 | "prettier": "^2.0.5", 43 | "pretty-quick": "^2.0.1", 44 | "react-dom": "^16.13.1", 45 | "styled-components": "^5.2.1", 46 | "styled-system": "^5.1.5", 47 | "typescript": "^4.2.4" 48 | }, 49 | "husky": { 50 | "hooks": { 51 | "pre-commit": "pretty-quick --staged" 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/LoadingSpinner.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import styled from "styled-components"; 3 | import css, { SystemStyleObject } from "@styled-system/css"; 4 | import { BaseSVG } from "./index"; 5 | 6 | export type LoadingSpinnerProps = { 7 | foreground?: string; 8 | background?: string; 9 | light?: boolean; 10 | dark?: boolean; 11 | }; 12 | 13 | const Foreground = styled.path(({ foreground }: LoadingSpinnerProps) => 14 | css({ 15 | fill: foreground, 16 | } as SystemStyleObject) 17 | ); 18 | 19 | const Background = styled.path(({ background }: LoadingSpinnerProps) => 20 | css({ 21 | fill: background, 22 | } as SystemStyleObject) 23 | ); 24 | 25 | export const LoadingSpinner = ({ 26 | foreground = "blue", 27 | background = "scales.blue20", 28 | light = false, 29 | dark = false, 30 | ...props 31 | }: LoadingSpinnerProps) => ( 32 | 33 | 41 | 45 | 54 | 55 | 56 | ); 57 | 58 | LoadingSpinner.displayName = "LoadingSpinner"; 59 | -------------------------------------------------------------------------------- /src/ManagedRadioButtonField.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import styled from "styled-components"; 3 | import { useField } from "formik"; 4 | import { BaseLabel, Label, ErrorLabel, RadioButton, Box, Col } from "./index"; 5 | import { StructureProps } from "./system/unions"; 6 | 7 | type ManagedRadioButtonFieldProps = StructureProps & { 8 | caption?: string; 9 | label: string; 10 | id: string; 11 | name: string; 12 | disabled?: boolean; 13 | }; 14 | 15 | // Hide this input completely 16 | const HiddenInput = styled.input` 17 | position: absolute; 18 | opacity: 0; 19 | height: 0; 20 | width: 0; 21 | margin: 0px; 22 | `; 23 | 24 | export const ManagedRadioButtonField = ({ 25 | label, 26 | caption, 27 | id, 28 | disabled, 29 | name, 30 | ...props 31 | }: ManagedRadioButtonFieldProps) => { 32 | // This differs slightly from MangaedCheckboxField 33 | const [field, meta, { setTouched }] = useField({ 34 | name, 35 | id, 36 | value: id, 37 | type: "radio", 38 | }); 39 | 40 | // Chrome and Safari do not send blur events properly 41 | const onChange = React.useCallback( 42 | (e: React.ChangeEvent) => { 43 | setTouched(true); 44 | field.onChange(e); 45 | }, 46 | [field.onChange, setTouched] 47 | ); 48 | 49 | return ( 50 | 51 | 57 | 64 | 65 | 66 | {caption ? ( 67 | 70 | ) : null} 71 | 80 | 81 | {meta.error} 82 | 83 | 84 | 85 | 86 | ); 87 | }; 88 | -------------------------------------------------------------------------------- /scripts/temp_migrate.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const path = require("path"); 3 | 4 | const src = __dirname + "/../src"; 5 | 6 | const exclude = [ 7 | ".DS_Store", 8 | "util.ts", 9 | "index.tsx", 10 | "index.ts", 11 | "iconIndex.tsx", 12 | ]; 13 | 14 | const include = [".tsx"]; 15 | 16 | const excludeExt = [".json", ".md"]; 17 | 18 | const basicDocjs = (name) => `<${name}> `; 19 | const basicReadme = (name) => ` 20 | # ${name} 21 | 22 | ## Purpose 23 | 24 | ## Usage 25 | 26 | ### Related 27 | 28 | | Library | Github | NPM | 29 | | ------------ | ----------------------------------------- | ------------------------------------------------ | 30 | | indigo-light | https://www.github.com/urbit/indigo-light | https://www.npmjs.com/package/@tlon/indigo-light | 31 | | indigo-dark | https://www.github.com/urbit/indigo-dark | https://www.npmjs.com/package/@tlon/indigo-dark | 32 | | indigo-react | https://www.github.com/urbit/indigo-react | https://www.npmjs.com/package/@tlon/indigo-react | 33 | 34 | ### License 35 | 36 | MIT License © [Tlon](https://tlon.io) 37 | `; 38 | 39 | const sourceFiles = fs 40 | .readdirSync(src) 41 | .map((sourcePath) => path.parse(sourcePath)) 42 | // .filter((parsedPath) => include.includes(parsedPath.ext)) 43 | .filter((parsedPath) => !exclude.includes(parsedPath.base)) 44 | .filter((parsedPath) => !excludeExt.includes(parsedPath.ext)); 45 | 46 | // sourceFiles.map((parsedPath) => fs.mkdirSync(src + "/" + parsedPath.name)); 47 | 48 | console.log(sourceFiles); 49 | 50 | sourceFiles.map((parsedPath) => { 51 | // const oldPath = src + "/" + parsedPath.base; 52 | // const newPath = src + "/" + parsedPath.name + "/" + parsedPath.base; 53 | // console.log(oldPath, newPath); 54 | // fs.renameSync(oldPath, newPath, function (err) { 55 | // if (err) throw err; 56 | // // console.log('Successfully renamed - AKA moved!') 57 | // }); 58 | // const readmePath = src + "/" + parsedPath.name + "/" + "README.md"; 59 | const docsJsonPath = src + "/" + parsedPath.name + "/" + "docs.json"; 60 | 61 | const docsJsPath = src + "/" + parsedPath.name + "/" + "docs.js"; 62 | 63 | if (fs.existsSync(docsJsonPath)) { 64 | fs.unlinkSync(docsJsonPath); 65 | } 66 | // fs.writeFileSync(readmePath, basicReadme(parsedPath.name), "utf8"); 67 | 68 | if (fs.existsSync(docsJsPath)) { 69 | // do something 70 | } else { 71 | fs.writeFileSync(docsJsPath, basicDocjs(parsedPath.name), "utf8"); 72 | } 73 | }); 74 | 75 | // console.log(sourceFiles) 76 | -------------------------------------------------------------------------------- /docs/src/components/Sidebar.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import styled from "styled-components"; 3 | import { 4 | Box, 5 | Row, 6 | Col, 7 | Text, 8 | Label, 9 | Rule, 10 | BaseImage, 11 | } from "local-indigo-react"; 12 | import manifest from "../../public/manifest.json"; 13 | import { Manifest, ComponentEntry } from "../types"; 14 | import { SidebarLink } from "./SidebarLink"; 15 | import { SidebarAnchor } from "./SidebarAnchor"; 16 | import { VersionTag } from "./VersionTag"; 17 | import { version } from "../../../package.json"; 18 | import { links } from "../constants"; 19 | 20 | export const Sidebar = () => ( 21 | 22 | 29 | 30 | Indigo 31 | 32 |
33 | {version} 34 |
35 |
36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 52 | 53 | Github 54 | 55 | 56 | NPM 57 | 58 | 59 | Figma 60 | 61 | 62 | 63 | 64 | 65 | 66 | 75 | 76 | Theme Viewer 77 | 78 | 79 | 80 | 81 | 82 | 83 | 92 | {manifest.components.map((component: ComponentEntry) => ( 93 | 94 | {component.displayName} 95 | 96 | ))} 97 | 98 | 99 | ); 100 | -------------------------------------------------------------------------------- /src/system/unions.ts: -------------------------------------------------------------------------------- 1 | import { 2 | background, 3 | border, 4 | color, 5 | flexbox, 6 | grid, 7 | textAlign, 8 | opacity, 9 | layout, 10 | position, 11 | shadow, 12 | space, 13 | typography, 14 | system, 15 | BackgroundProps, 16 | BorderProps, 17 | ColorProps, 18 | FlexboxProps, 19 | GridProps, 20 | LayoutProps, 21 | PositionProps, 22 | ShadowProps, 23 | SpaceProps, 24 | TypographyProps, 25 | OpacityProps, 26 | OverflowProps, 27 | TextAlignProps, 28 | } from "styled-system"; 29 | 30 | export type SystemProps = { 31 | cursor?: string; 32 | textOverflow?: string; 33 | whiteSpace?: string; 34 | textTransform?: string; 35 | }; 36 | 37 | export type AllSystemProps = SystemProps & 38 | BackgroundProps & 39 | BorderProps & 40 | ColorProps & 41 | FlexboxProps & 42 | GridProps & 43 | LayoutProps & 44 | PositionProps & 45 | ShadowProps & 46 | SpaceProps & 47 | OpacityProps & 48 | OverflowProps & 49 | TextAlignProps & 50 | TypographyProps; 51 | 52 | export const allSystemStyle = [ 53 | background, 54 | border, 55 | color, 56 | flexbox, 57 | grid, 58 | textAlign, 59 | opacity, 60 | layout, 61 | position, 62 | shadow, 63 | space, 64 | typography, 65 | system({ 66 | cursor: true, 67 | textOverflow: true, 68 | whiteSpace: true, 69 | textTransform: true, 70 | }), 71 | ]; 72 | 73 | export type CommonStyleProps = SystemProps & 74 | BorderProps & 75 | ColorProps & 76 | FlexboxProps & 77 | GridProps & 78 | LayoutProps & 79 | SpaceProps & 80 | TypographyProps; 81 | 82 | export const commonStyle = [ 83 | border, 84 | color, 85 | flexbox, 86 | grid, 87 | layout, 88 | space, 89 | typography, 90 | ]; 91 | 92 | export type CosmeticProps = SystemProps & 93 | BackgroundProps & 94 | BorderProps & 95 | ColorProps & 96 | ShadowProps & 97 | OpacityProps; 98 | 99 | export const cosmeticStyle = [ 100 | background, 101 | border, 102 | color, 103 | opacity, 104 | shadow, 105 | system({ 106 | cursor: true, 107 | }), 108 | ]; 109 | 110 | export type StructureProps = SystemProps & 111 | BorderProps & 112 | FlexboxProps & 113 | GridProps & 114 | LayoutProps & 115 | PositionProps & 116 | SpaceProps & 117 | OverflowProps; 118 | 119 | export const structureStyle = [ 120 | border, 121 | flexbox, 122 | grid, 123 | layout, 124 | position, 125 | space, 126 | system({ 127 | cursor: true, 128 | }), 129 | ]; 130 | 131 | export type TypographicProps = ColorProps & 132 | TextAlignProps & 133 | TypographyProps & { 134 | textOverflow?: string; 135 | whiteSpace?: string; 136 | textTransform?: string; 137 | }; 138 | 139 | export const typographicStyle = [ 140 | color, 141 | textAlign, 142 | typography, 143 | system({ 144 | cursor: true, 145 | textOverflow: true, 146 | whiteSpace: true, 147 | textTransform: true, 148 | }), 149 | ]; 150 | 151 | export const listStyle = [...allSystemStyle, system({ listStyle: true })]; 152 | export type ListProps = AllSystemProps & { 153 | listStyle?: string; 154 | } 155 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [ARCHIVED] indigo-react 2 | 3 | [![npm (scoped)](https://img.shields.io/npm/v/@tlon/indigo-react?style=flat)](https://www.npmjs.com/package/@tlon/indigo-react) 4 | 5 | Indigo React is a component library for implementing the [Indigo Design System](). It's built with React, [styled-components](https://styled-components.com) and [styled-system](https://styled-system.com). It also uses [Formik](https://formik.org/) and [Reach-UI](https://reach.tech/). 6 | 7 | ## Quick Start 8 | 9 | 1. Install the library 10 | 11 | ```bash 12 | npm install --save @tlon/indigo-react 13 | ``` 14 | 15 | 2. Install peer dependencies 16 | 17 | ```bash 18 | npm install --save @tlon/indigo-light styled-components styled-system react react-dom @reach/disclosure @reach/menu-button @reach/tabs markdown-to-jsx formik 19 | ``` 20 | 21 | If you are using Typescript, install the type definitions for several of these libraries. 22 | 23 | ```bash 24 | npm install --save @types/styled-components @types/styled-system @types/styled-system__css 25 | ``` 26 | 27 | 3. Install a theme 28 | 29 | ```bash 30 | npm install --save @tlon/indigo-light @tlon/indigo-dark 31 | ``` 32 | 33 | ## Basic Usage 34 | 35 | ```js 36 | import * as React from "react"; 37 | import { ThemeProvider } from "styled-system"; 38 | import { Text, Reset } from "@tlon/indigo-react"; 39 | import light from "@tlon/indigo-light"; 40 | 41 | class App extends React.Component { 42 | render() { 43 | return ( 44 | 45 | 46 | Indigo! 47 | 48 | ); 49 | } 50 | } 51 | ``` 52 | 53 | In the above, we are wrapping our application in styled-component's `ThemeProvider` and passing in our `theme` from `@tlon/indigo-light`. In practice, you should rarely need to import the theme. 54 | 55 | The `` component accepts a fontSize prop, which is one of many style props provided by `styled-system`. Using VSCode is the best way to see the list of props each component can accept. 56 | 57 | You can also check out the [styled-system docs](https://styled-system.com/api) for a breakdown of props. 58 | 59 | Many of these props have corrosponding styling shortcuts, drawn from the provided theme, like `@tlon/indigo-light`. These shortcuts are also provided by `styled-system`. To see how props map to values in our theme, check out [styled-system's mapping](https://styled-system.com/table). 60 | 61 | Take a look at the [theme](https://www.github.com/urbit/indigo-light) to get a sense for which style values can be accessed from styled props. 62 | 63 | ## Development 64 | 65 | See [DEVELOPMENT.md](https://github.com/urbit/indigo-react/blob/master/DEVELOPMENT.md) for example cases of component patterns used to create Indigo. 66 | 67 | ### Related 68 | 69 | | Library | Github | NPM | 70 | | ------------ | ----------------------------------------- | ------------------------------------------------ | 71 | | indigo-light | https://www.github.com/urbit/indigo-light | https://www.npmjs.com/package/@tlon/indigo-light | 72 | | indigo-dark | https://www.github.com/urbit/indigo-dark | https://www.npmjs.com/package/@tlon/indigo-dark | 73 | | indigo-react | https://www.github.com/urbit/indigo-react | https://www.npmjs.com/package/@tlon/indigo-react | 74 | 75 | ### License 76 | 77 | MIT License © [Tlon](https://tlon.io) 78 | -------------------------------------------------------------------------------- /docs/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "componentCount": 54, 3 | "components": [ 4 | { "id": "action", "displayName": "Action" }, 5 | { "id": "actionAnchor", "displayName": "ActionAnchor" }, 6 | { "id": "anchor", "displayName": "Anchor" }, 7 | { "id": "aspectRatio", "displayName": "AspectRatio" }, 8 | { "id": "backgroundImage", "displayName": "BackgroundImage" }, 9 | { "id": "baseAnchor", "displayName": "BaseAnchor" }, 10 | { "id": "baseButton", "displayName": "BaseButton" }, 11 | { "id": "baseCode", "displayName": "BaseCode" }, 12 | { "id": "baseForm", "displayName": "BaseForm" }, 13 | { "id": "baseImage", "displayName": "BaseImage" }, 14 | { "id": "baseInput", "displayName": "BaseInput" }, 15 | { "id": "baseLabel", "displayName": "BaseLabel" }, 16 | { "id": "baseSVG", "displayName": "BaseSVG" }, 17 | { "id": "baseTextArea", "displayName": "BaseTextArea" }, 18 | { "id": "box", "displayName": "Box" }, 19 | { "id": "button", "displayName": "Button" }, 20 | { "id": "buttonAnchor", "displayName": "ButtonAnchor" }, 21 | { "id": "center", "displayName": "Center" }, 22 | { "id": "checkbox", "displayName": "Checkbox" }, 23 | { "id": "col", "displayName": "Col" }, 24 | { "id": "continuousProgressBar", "displayName": "ContinuousProgressBar" }, 25 | { "id": "disclosureBox", "displayName": "DisclosureBox" }, 26 | { "id": "disclosureButton", "displayName": "DisclosureButton" }, 27 | { "id": "errorLabel", "displayName": "ErrorLabel" }, 28 | { "id": "formController", "displayName": "FormController" }, 29 | { "id": "fourUp", "displayName": "FourUp" }, 30 | { "id": "icon", "displayName": "Icon" }, 31 | { "id": "indicator", "displayName": "Indicator" }, 32 | { "id": "inline", "displayName": "Inline" }, 33 | { "id": "label", "displayName": "Label" }, 34 | { "id": "loadingSpinner", "displayName": "LoadingSpinner" }, 35 | { "id": "managedCheckboxField", "displayName": "ManagedCheckboxField" }, 36 | { "id": "managedForm", "displayName": "ManagedForm" }, 37 | { 38 | "id": "managedRadioButtonField", 39 | "displayName": "ManagedRadioButtonField" 40 | }, 41 | { "id": "managedTextAreaField", "displayName": "ManagedTextAreaField" }, 42 | { "id": "managedTextInputField", "displayName": "ManagedTextInputField" }, 43 | { 44 | "id": "managedToggleSwitchField", 45 | "displayName": "ManagedToggleSwitchField" 46 | }, 47 | { "id": "menu", "displayName": "Menu" }, 48 | { "id": "menuButton", "displayName": "MenuButton" }, 49 | { "id": "menuItem", "displayName": "MenuItem" }, 50 | { "id": "menuList", "displayName": "MenuList" }, 51 | { "id": "radioButton", "displayName": "RadioButton" }, 52 | { "id": "reset", "displayName": "Reset" }, 53 | { "id": "row", "displayName": "Row" }, 54 | { "id": "rule", "displayName": "Rule" }, 55 | { "id": "segmentedProgressBar", "displayName": "SegmentedProgressBar" }, 56 | { "id": "statelessCheckboxField", "displayName": "StatelessCheckboxField" }, 57 | { 58 | "id": "statelessRadioButtonField", 59 | "displayName": "StatelessRadioButtonField" 60 | }, 61 | { "id": "statelessTextArea", "displayName": "StatelessTextArea" }, 62 | { "id": "statelessTextInput", "displayName": "StatelessTextInput" }, 63 | { 64 | "id": "statelessToggleSwitchField", 65 | "displayName": "StatelessToggleSwitchField" 66 | }, 67 | { "id": "text", "displayName": "Text" }, 68 | { "id": "toggleSwitch", "displayName": "ToggleSwitch" }, 69 | { "id": "twoUp", "displayName": "TwoUp" } 70 | ] 71 | } 72 | -------------------------------------------------------------------------------- /docs/src/components/ComponentPreview.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import styled from "styled-components"; 3 | import { useState, useEffect } from "react"; 4 | import * as indigo from "local-indigo-react"; 5 | import { 6 | Col, 7 | Text, 8 | TwoUp, 9 | Center, 10 | commonStyle, 11 | CommonStyleProps, 12 | } from "local-indigo-react"; 13 | import { 14 | LiveProvider, 15 | LiveEditor as ReactLiveLiveEditor, 16 | LiveError as ReactLiveLiveError, 17 | LivePreview as ReactLiveLivePreview, 18 | } from "react-live"; 19 | import { ComponentProperties } from "../types"; 20 | 21 | export const LiveEditor = styled(ReactLiveLiveEditor)< 22 | React.PropsWithChildren 23 | >({}, ...commonStyle); 24 | 25 | export const LiveError = styled(ReactLiveLiveError)< 26 | React.PropsWithChildren 27 | >({}, ...commonStyle); 28 | 29 | export const LivePreview = styled(ReactLiveLivePreview)< 30 | React.PropsWithChildren 31 | >({}, ...commonStyle); 32 | 33 | const scope = { ...indigo, useState, useEffect }; 34 | 35 | const theme = { 36 | plain: { 37 | color: "rgba(0,0,0,0.6)", 38 | backgroundColor: "rgba(0,0,0,0.04)", 39 | }, 40 | styles: [ 41 | { 42 | types: ["prolog"], 43 | style: { 44 | color: "rgb(0, 0, 128)", 45 | }, 46 | }, 47 | { 48 | types: ["comment"], 49 | style: { 50 | color: "rgba(0,0,0,0.6)", 51 | }, 52 | }, 53 | { 54 | types: ["builtin", "changed", "keyword"], 55 | style: { 56 | color: "#FF4136", 57 | }, 58 | }, 59 | { 60 | types: ["number", "inserted"], 61 | style: { 62 | color: "rgb(181, 206, 168)", 63 | }, 64 | }, 65 | { 66 | types: ["constant"], 67 | style: { 68 | color: "rgb(100, 102, 149)", 69 | }, 70 | }, 71 | { 72 | types: ["attr-name", "variable"], 73 | style: { 74 | color: "rgb(156, 220, 254)", 75 | }, 76 | }, 77 | { 78 | types: ["deleted", "string", "attr-value"], 79 | style: { 80 | color: "rgb(206, 145, 120)", 81 | }, 82 | }, 83 | { 84 | types: ["selector"], 85 | style: { 86 | color: "rgb(215, 186, 125)", 87 | }, 88 | }, 89 | { 90 | // Fix tag color 91 | types: ["tag"], 92 | style: { 93 | color: "rgb(78, 201, 176)", 94 | }, 95 | }, 96 | { 97 | // Fix tag color for HTML 98 | types: ["tag"], 99 | languages: ["markup"], 100 | style: { 101 | color: "rgb(86, 156, 214)", 102 | }, 103 | }, 104 | { 105 | types: ["punctuation", "operator"], 106 | style: { 107 | color: "rgba(0,0,0,1)", 108 | }, 109 | }, 110 | { 111 | // Fix punctuation color for HTML 112 | types: ["punctuation"], 113 | languages: ["markup"], 114 | style: { 115 | color: "rgba(0,0,0,0.8)", 116 | }, 117 | }, 118 | { 119 | types: ["function"], 120 | style: { 121 | color: "#9D52FF", 122 | }, 123 | }, 124 | { 125 | types: ["class-name"], 126 | style: { 127 | color: "#009F65", 128 | }, 129 | }, 130 | { 131 | types: ["char"], 132 | style: { 133 | color: "rgb(209, 105, 105)", 134 | }, 135 | }, 136 | ], 137 | }; 138 | 139 | export type ComponentPreviewProps = { 140 | properties: ComponentProperties; 141 | }; 142 | 143 | export const resetReactLive = { 144 | fontFamily: "", 145 | padding: "", 146 | }; 147 | 148 | export const ComponentPreview = ({ properties }: ComponentPreviewProps) => ( 149 | 150 | 151 | 152 | 158 | 159 | 160 |
161 | 162 |
163 |
164 |
165 | ); 166 | -------------------------------------------------------------------------------- /CHANGELOG: -------------------------------------------------------------------------------- 1 | 2 | # Changelog 3 | 1.2.17 (2021-1-20) 4 | * adds hideDisabled prop to Button and Action 5 | 6 | 1.2.16 (2021-1-11) 7 | * Updates all elements to use new typography 8 | * Removes AnchorButton and ActionAnchor because they are redundant given 'as' prop 9 | 10 | 1.2.15 (2020-11-11) 11 | * Removes position:relative from 12 | * Removes flex:0 to row and col 13 | 14 | 1.2.14 (2020-11-11) 15 | * Adds LargeBullet for notification badge 16 | * Adds flex:0 to row and col for cross-browser compatibility 17 | 18 | 1.2.13 (2020-10-29) 19 | * Disables svg fill property target in Button 20 | 21 | 1.2.12 (2020-10-29) 22 | * Fixes spaces icon 23 | 24 | -1.2.11 (2020-10-29) 25 | * Spaces Icon 26 | * Add Users Icon 27 | * fixes white space etc on Text 28 | * Smaller triangle icons 29 | 30 | - 1.2.10 (2020-10-7) 31 | * Exports IconIndex 32 | * Adds textTransform to AllSystemProps and TypographyProps 33 | 34 | - 1.2.9 (2020-10-7) 35 | * Adds textOverflow and whiteSpace to AllSystemProps and TypographyProps 36 | * Adds more icons 37 | * Adds Badge 38 | * Resolves onBlur behavior from 1.2.8 39 | 40 | - 1.2.8 (2020-10-6) 41 | * Adds Badge 42 | * Adds several icons 43 | * Updates several icons 44 | 45 | - 1.2.7 (2020-9-25) 46 | * Fixes gy prop on col, which should have been gapY 47 | * Revises Boot and Download Icons 48 | * ActionAnchor is no longer centered 49 | 50 | - 1.2.6 (2020-9-23) 51 | * Adds FourUp 52 | * Implements FourUp and TwoUp with css grid 53 | * Row and Col 'pitch' prop now gapX and gapY respectively 54 | 55 | - 1.2.5 (2020-9-22) 56 | * ManagedTextInputField and ManagedTextAreaField removes own vertical margin when no label or title is given 57 | * Icon accepts a stroke prop 58 | * Formik is now not bundled, and should be installed as a peer dep 59 | 60 | - 1.2.4 (2020-9-1) 61 | * Adds boot and upload icon 62 | * Adds CSS grid props 63 | * Fixes cursor typings 64 | * TwoUp can apply gutter spacing 65 | * Removes FourUp 66 | 67 | - 1.2.3 (2020-8-28) 68 | * Drop minification from release build process because it causes issues downstream. 69 | 70 | - 1.2.2 (2020-08-21) 71 | * Adds asButton, asAnchor and asAction functions. 72 | * Action horizontal text alignment now left and container is no longer a flexbox. 73 | * Label has fixed height and uses flexbox. 74 | * TextArea and TextInput accept fontFamily, fontWeight, color, backgroundColor, borderColor 75 | * Text is now a span so that it can be nested inside the Paragraph component 76 | * Inline is now Paragraph and is a p tag 77 | 78 | - 1.2.1 (2020-08-20) 79 | * Adds SegmentedProgressBar, ContinuousProgressBar 80 | * Adds LoadingSpinner 81 | * Gives MenuButton correct x pad and justify-between 82 | * Adds ActionAnchor 83 | * Reorganizes library files to accommodate better documentation 84 | * Adds scripts which generate basic documentation for docs site 85 | * Adds skeleton of a docs site 86 | 87 | - 1.2.0 (2020-08-17) 88 | * Renames BackgroundImg to BackgroundImage 89 | * Renames Img to Image 90 | * Adds top and bottom caps on Menu 91 | * Removes props on MenuButton. It now has same optional props as Button. 92 | * Renames Disclosure to DisclosureBox 93 | * Disclosure Box now does not use Reach UI 94 | * Adds cursor prop 95 | * Adds /examples 96 | * CSS Reset is now a component called Resest, instead of a string 97 | * Generally expands prop options on components 98 | * New Components: Action, AspectRatio, BaseForm, BaseAnchor, BaseButton, BaseCode, BaseImage, BaseInput, BaseLabel, BaseSVG, BaseTextArea, Checkbox, RadioButton, Indicator, ToggleSwitch, ErrorLabel, Inline, ManagedCheckboxField, ManagedForm, FormController, ManagedRadioButtonField, ManagedTextInputField, ManagedToggleSwitchField, Reset, StatelessCheckboxField, StatelessTextArea, StatelessTextInput and StatelessToggleSwitchField 99 | * New Icons: Smiley, Heart, XSmall, PlusSmall, Weather, Clock, Chat, Links, Publish, Groups, Gear, LeapArrow, Home, TrashCan 100 | * Resolves non-DOM properties being forwarded to DOM 101 | * Resolves cases where React typings overlapped with incompatible styled-system properties of the same name 102 | * Adds DEVELOPMENT.md with component reference patterns -------------------------------------------------------------------------------- /src/index.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Box 3 | */ 4 | export { Box, BoxProps } from "./Box"; 5 | 6 | /** 7 | * Text + Type + Icons 8 | */ 9 | export { Text, TextProps } from "./Text"; 10 | export { H1, H1Props } from "./H1"; 11 | export { H2, H2Props } from "./H2"; 12 | export { H3, H3Props } from "./H3"; 13 | export { H4, H4Props } from "./H4"; 14 | export { Label, LabelProps } from "./Label"; 15 | export { ErrorLabel, ErrorLabelProps } from "./ErrorLabel"; 16 | export { Icon, IconProps, IconIndex } from "./Icon"; 17 | export { iconIndex as _iconIndex } from "./iconIndex"; 18 | export { Image, ImageProps } from "./Image"; 19 | export { Badge } from "./Badge"; 20 | /** 21 | * Layout 22 | */ 23 | export { Ol, OlProps } from "./Ol"; 24 | export { Ul, UlProps } from "./Ul"; 25 | export { Li, LiProps } from "./Li"; 26 | export { Row, RowProps } from "./Row"; 27 | export { Col, ColProps } from "./Col"; 28 | export { Paragraph, ParagraphProps } from "./Paragraph"; 29 | export { Center, CenterProps } from "./Center"; 30 | export { Rule, RuleProps } from "./Rule"; 31 | export { AspectRatio, AspectRatioProps } from "./AspectRatio"; 32 | export { TwoUp, TwoUpProps } from "./TwoUp"; 33 | export { FourUp, FourUpProps } from "./FourUp"; 34 | export { Table, TableProps } from "./Table"; 35 | export { Tr, TrProps } from "./Tr"; 36 | export { Td, TdProps } from "./Td"; 37 | 38 | /** 39 | * Buttons + Anchors 40 | */ 41 | export { Action, ActionProps, asAction } from "./Action"; 42 | export { Button, ButtonProps, asButton } from "./Button"; 43 | export { Anchor, AnchorProps, asAnchor } from "./Anchor"; 44 | 45 | /** 46 | * Controls 47 | */ 48 | export { DisclosureBox, DisclosureBoxProps } from "./DisclosureBox"; 49 | export { DisclosureButton, DisclosureButtonProps } from "./DisclosureButton"; 50 | // These create a lot of extra tsc build time burden. You can temporarily disable them to speed up your dev build. 51 | export { Menu, MenuProps } from "./Menu"; 52 | export { MenuButton, MenuButtonProps } from "./MenuButton"; 53 | export { MenuItem, MenuItemProps } from "./MenuItem"; 54 | export { MenuList, MenuListProps } from "./MenuList"; 55 | 56 | /** 57 | * Base Components 58 | */ 59 | export { BaseAnchor, BaseAnchorProps } from "./BaseAnchor"; 60 | export { BaseButton, BaseButtonProps } from "./BaseButton"; 61 | export { BaseImage, BaseImageProps } from "./BaseImage"; 62 | export { BaseInput, BaseInputProps } from "./BaseInput"; 63 | export { BaseTextArea, BaseTextAreaProps } from "./BaseTextArea"; 64 | export { BaseLabel, BaseLabelProps } from "./BaseLabel"; 65 | export { BaseCode, BaseCodeProps } from "./BaseCode"; 66 | export { BaseForm, BaseFormProps } from "./BaseForm"; 67 | export { BaseSVG, BaseSVGProps } from "./BaseSVG"; 68 | 69 | /** 70 | * Stateless Fields 71 | */ 72 | export { 73 | StatelessCheckboxField, 74 | StatelessCheckboxFieldProps, 75 | } from "./StatelessCheckboxField"; 76 | export { 77 | StatelessRadioButtonField, 78 | StatelessRadioButtonFieldProps, 79 | } from "./StatelessRadioButtonField"; 80 | export { 81 | StatelessToggleSwitchField, 82 | StatelessToggleSwitchFieldProps, 83 | } from "./StatelessToggleSwitchField"; 84 | 85 | /** 86 | * Form Parts 87 | */ 88 | export { Indicator, IndicatorProps } from "./Indicator"; 89 | export { Checkbox, CheckboxProps } from "./Checkbox"; 90 | export { ToggleSwitch, ToggleSwitchProps } from "./ToggleSwitch"; 91 | export { RadioButton, RadioButtonProps } from "./RadioButton"; 92 | export { 93 | StatelessTextInput, 94 | StatelessTextInputProps, 95 | } from "./StatelessTextInput"; 96 | export { StatelessTextArea, StatelessTextAreaProps } from "./StatelessTextArea"; 97 | 98 | /** 99 | * Managed Fields 100 | */ 101 | export { ManagedForm } from "./ManagedForm"; 102 | export { FormController } from "./FormController"; 103 | export { ManagedTextInputField } from "./ManagedTextInputField"; 104 | export { ManagedTextAreaField } from "./ManagedTextAreaField"; 105 | export { ManagedCheckboxField } from "./ManagedCheckboxField"; 106 | export { ManagedRadioButtonField } from "./ManagedRadioButtonField"; 107 | export { ManagedToggleSwitchField } from "./ManagedToggleSwitchField"; 108 | 109 | /** 110 | * Indication 111 | */ 112 | export { ContinuousProgressBar } from "./ContinuousProgressBar"; 113 | export { 114 | SegmentedProgressBar, 115 | SegmentedProgressBarProps, 116 | } from "./SegmentedProgressBar"; 117 | export { LoadingSpinner, LoadingSpinnerProps } from "./LoadingSpinner"; 118 | 119 | /** 120 | * Utility 121 | */ 122 | export { Reset } from "./Reset"; 123 | export { 124 | AllSystemProps, 125 | allSystemStyle, 126 | CosmeticProps, 127 | cosmeticStyle, 128 | StructureProps, 129 | structureStyle, 130 | commonStyle, 131 | CommonStyleProps, 132 | TypographicProps, 133 | typographicStyle, 134 | } from "./system/unions"; 135 | 136 | /** 137 | * Test Themes 138 | */ 139 | export { light as _light } from "./themes/light"; 140 | export { dark as _dark } from "./themes/dark"; 141 | export { Theme } from "./themes/light"; 142 | -------------------------------------------------------------------------------- /src/themes/dark.ts: -------------------------------------------------------------------------------- 1 | import baseStyled, { ThemedStyledInterface } from "styled-components"; 2 | 3 | const base = { 4 | white: "rgba(255,255,255,1)", 5 | black: "rgba(26,26,26,1)", 6 | red: "rgba(255,65,54,1)", 7 | yellow: "rgba(255,199,0,1)", 8 | green: "rgba(0,159,101,1)", 9 | blue: "rgba(0,142,255,1)", 10 | }; 11 | 12 | const scales = { 13 | black05: "rgba(255,255,255,0.05)", 14 | black10: "rgba(255,255,255,0.1)", 15 | black20: "rgba(255,255,255,0.2)", 16 | black30: "rgba(255,255,255,0.3)", 17 | black40: "rgba(255,255,255,0.4)", 18 | black50: "rgba(255,255,255,0.5)", 19 | black60: "rgba(255,255,255,0.6)", 20 | black70: "rgba(255,255,255,0.7)", 21 | black80: "rgba(255,255,255,0.8)", 22 | black90: "rgba(255,255,255,0.9)", 23 | black100: "rgba(255,255,255,1)", 24 | white05: "rgba(0,0,0,0.05)", 25 | white10: "rgba(0,0,0,0.1)", 26 | white20: "rgba(0,0,0,0.2)", 27 | white30: "rgba(0,0,0,0.3)", 28 | white40: "rgba(0,0,0,0.4)", 29 | white50: "rgba(0,0,0,0.5)", 30 | white60: "rgba(0,0,0,0.6)", 31 | white70: "rgba(0,0,0,0.7)", 32 | white80: "rgba(0,0,0,0.8)", 33 | white90: "rgba(0,0,0,0.9)", 34 | white100: "rgba(0,0,0,1)", 35 | red05: "rgba(255,65,54,0.05)", 36 | red10: "rgba(255,65,54,0.1)", 37 | red20: "rgba(255,65,54,0.2)", 38 | red30: "rgba(255,65,54,0.3)", 39 | red40: "rgba(255,65,54,0.4)", 40 | red50: "rgba(255,65,54,0.5)", 41 | red60: "rgba(255,65,54,0.6)", 42 | red70: "rgba(255,65,54,0.7)", 43 | red80: "rgba(255,65,54,0.8)", 44 | red90: "rgba(255,65,54,0.9)", 45 | red100: "rgba(255,65,54,1)", 46 | yellow05: "rgba(255,199,0,0.05)", 47 | yellow10: "rgba(255,199,0,0.1)", 48 | yellow20: "rgba(255,199,0,0.2)", 49 | yellow30: "rgba(255,199,0,0.3)", 50 | yellow40: "rgba(255,199,0,0.4)", 51 | yellow50: "rgba(255,199,0,0.5)", 52 | yellow60: "rgba(255,199,0,0.6)", 53 | yellow70: "rgba(255,199,0,0.7)", 54 | yellow80: "rgba(255,199,0,0.8)", 55 | yellow90: "rgba(255,199,0,0.9)", 56 | yellow100: "rgba(255,199,0,1)", 57 | green05: "rgba(0,159,101,0.05)", 58 | green10: "rgba(0,159,101,0.1)", 59 | green20: "rgba(0,159,101,0.2)", 60 | green30: "rgba(0,159,101,0.3)", 61 | green40: "rgba(0,159,101,0.4)", 62 | green50: "rgba(0,159,101,0.5)", 63 | green60: "rgba(0,159,101,0.6)", 64 | green70: "rgba(0,159,101,0.7)", 65 | green80: "rgba(0,159,101,0.8)", 66 | green90: "rgba(0,159,101,0.9)", 67 | green100: "rgba(0,159,101,1)", 68 | blue05: "rgba(0,142,255,0.05)", 69 | blue10: "rgba(0,142,255,0.1)", 70 | blue20: "rgba(0,142,255,0.2)", 71 | blue30: "rgba(0,142,255,0.3)", 72 | blue40: "rgba(0,142,255,0.4)", 73 | blue50: "rgba(0,142,255,0.5)", 74 | blue60: "rgba(0,142,255,0.6)", 75 | blue70: "rgba(0,142,255,0.7)", 76 | blue80: "rgba(0,142,255,0.8)", 77 | blue90: "rgba(0,142,255,0.9)", 78 | blue100: "rgba(0,142,255,1)", 79 | }; 80 | 81 | const util = { 82 | cyan: "#00FFFF", 83 | magenta: "#FF00FF", 84 | yellow: "#FFFF00", 85 | black: "#000000", 86 | }; 87 | 88 | export const dark = { 89 | colors: { 90 | white: base.black, 91 | black: base.white, 92 | 93 | gray: scales.black60, 94 | lightGray: scales.black30, 95 | washedGray: scales.black10, 96 | 97 | red: base.red, 98 | lightRed: scales.red30, 99 | washedRed: scales.red10, 100 | 101 | yellow: base.yellow, 102 | lightYellow: scales.yellow30, 103 | washedYellow: scales.yellow10, 104 | 105 | green: base.green, 106 | lightGreen: scales.green30, 107 | washedGreen: scales.green10, 108 | 109 | blue: base.blue, 110 | lightBlue: scales.blue30, 111 | washedBlue: scales.blue10, 112 | 113 | none: "rgba(0,0,0,0)", 114 | 115 | scales: scales, 116 | util: util, 117 | }, 118 | fonts: { 119 | sans: `"Inter", "Inter UI", -apple-system, BlinkMacSystemFont, 'San Francisco', 'Helvetica Neue', Arial, sans-serif`, 120 | mono: `"Source Code Pro", "Roboto mono", "Courier New", monospace`, 121 | }, 122 | // font-size 123 | fontSizes: [ 124 | 12, // 0 125 | 14, // 1 126 | 16, // 2 127 | 20, // 3 128 | 24, // 4 129 | 32, // 5 130 | 48, // 6 131 | 64, // 7 132 | ], 133 | // font-weight 134 | fontWeights: { 135 | thin: 300, 136 | regular: 400, 137 | bold: 500, 138 | }, 139 | // line-height 140 | lineHeights: { 141 | min: 1.2, 142 | short: 1.33334, 143 | regular: 1.5, 144 | tall: 1.66667, 145 | }, 146 | // border, border-top, border-right, border-bottom, border-left 147 | borders: ["none", "1px solid"], 148 | // margin, margin-top, margin-right, margin-bottom, margin-left, padding, padding-top, padding-right, padding-bottom, padding-left, grid-gap, grid-column-gap, grid-row-gap 149 | space: [ 150 | 0, // 0 151 | 4, // 1 152 | 8, // 2 153 | 16, // 3 154 | 24, // 4 155 | 32, // 5 156 | 48, // 6 157 | 64, // 7 158 | 96, // 8 159 | ], 160 | // border-radius 161 | radii: [ 162 | 0, // 0 163 | 2, // 1 164 | 4, // 2 165 | 8, // 3 166 | ], 167 | // width, height, min-width, max-width, min-height, max-height 168 | sizes: [ 169 | 0, // 0 170 | 4, // 1 171 | 8, // 2 172 | 16, // 3 173 | 24, // 4 174 | 32, // 5 175 | 48, // 6 176 | 64, // 7 177 | 96, // 8 178 | ], 179 | // z-index 180 | zIndices: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 181 | breakpoints: ["768px", "1024px", "1440px", "2200px"], 182 | }; 183 | export type Theme = typeof dark; 184 | export const styled = baseStyled as ThemedStyledInterface; 185 | -------------------------------------------------------------------------------- /src/themes/light.ts: -------------------------------------------------------------------------------- 1 | import baseStyled, { ThemedStyledInterface } from "styled-components"; 2 | 3 | const base = { 4 | white: "rgba(255,255,255,1)", 5 | black: "rgba(0,0,0,1)", 6 | red: "rgba(255,65,54,1)", 7 | yellow: "rgba(255,199,0,1)", 8 | green: "rgba(0,159,101,1)", 9 | blue: "rgba(33,157,255,1)", 10 | }; 11 | 12 | const scales = { 13 | white05: "rgba(255,255,255,0.05)", 14 | white10: "rgba(255,255,255,0.1)", 15 | white20: "rgba(255,255,255,0.2)", 16 | white30: "rgba(255,255,255,0.3)", 17 | white40: "rgba(255,255,255,0.4)", 18 | white50: "rgba(255,255,255,0.5)", 19 | white60: "rgba(255,255,255,0.6)", 20 | white70: "rgba(255,255,255,0.7)", 21 | white80: "rgba(255,255,255,0.8)", 22 | white90: "rgba(255,255,255,0.9)", 23 | white100: "rgba(255,255,255,1)", 24 | black05: "rgba(0,0,0,0.05)", 25 | black10: "rgba(0,0,0,0.1)", 26 | black20: "rgba(0,0,0,0.2)", 27 | black30: "rgba(0,0,0,0.3)", 28 | black40: "rgba(0,0,0,0.4)", 29 | black50: "rgba(0,0,0,0.5)", 30 | black60: "rgba(0,0,0,0.6)", 31 | black70: "rgba(0,0,0,0.7)", 32 | black80: "rgba(0,0,0,0.8)", 33 | black90: "rgba(0,0,0,0.9)", 34 | black100: "rgba(0,0,0,1)", 35 | red05: "rgba(255,65,54,0.05)", 36 | red10: "rgba(255,65,54,0.1)", 37 | red20: "rgba(255,65,54,0.2)", 38 | red30: "rgba(255,65,54,0.3)", 39 | red40: "rgba(255,65,54,0.4)", 40 | red50: "rgba(255,65,54,0.5)", 41 | red60: "rgba(255,65,54,0.6)", 42 | red70: "rgba(255,65,54,0.7)", 43 | red80: "rgba(255,65,54,0.8)", 44 | red90: "rgba(255,65,54,0.9)", 45 | red100: "rgba(255,65,54,1)", 46 | yellow05: "rgba(255,199,0,0.05)", 47 | yellow10: "rgba(255,199,0,0.1)", 48 | yellow20: "rgba(255,199,0,0.2)", 49 | yellow30: "rgba(255,199,0,0.3)", 50 | yellow40: "rgba(255,199,0,0.4)", 51 | yellow50: "rgba(255,199,0,0.5)", 52 | yellow60: "rgba(255,199,0,0.6)", 53 | yellow70: "rgba(255,199,0,0.7)", 54 | yellow80: "rgba(255,199,0,0.8)", 55 | yellow90: "rgba(255,199,0,0.9)", 56 | yellow100: "rgba(255,199,0,1)", 57 | green05: "rgba(0,159,101,0.05)", 58 | green10: "rgba(0,159,101,0.1)", 59 | green20: "rgba(0,159,101,0.2)", 60 | green30: "rgba(0,159,101,0.3)", 61 | green40: "rgba(0,159,101,0.4)", 62 | green50: "rgba(0,159,101,0.5)", 63 | green60: "rgba(0,159,101,0.6)", 64 | green70: "rgba(0,159,101,0.7)", 65 | green80: "rgba(0,159,101,0.8)", 66 | green90: "rgba(0,159,101,0.9)", 67 | green100: "rgba(0,159,101,1)", 68 | blue05: "rgba(33,157,255,0.05)", 69 | blue10: "rgba(33,157,255,0.1)", 70 | blue20: "rgba(33,157,255,0.2)", 71 | blue30: "rgba(33,157,255,0.3)", 72 | blue40: "rgba(33,157,255,0.4)", 73 | blue50: "rgba(33,157,255,0.5)", 74 | blue60: "rgba(33,157,255,0.6)", 75 | blue70: "rgba(33,157,255,0.7)", 76 | blue80: "rgba(33,157,255,0.8)", 77 | blue90: "rgba(33,157,255,0.9)", 78 | blue100: "rgba(33,157,255,1)", 79 | }; 80 | 81 | const util = { 82 | cyan: "#00FFFF", 83 | magenta: "#FF00FF", 84 | yellow: "#FFFF00", 85 | black: "#000000", 86 | }; 87 | 88 | export const light = { 89 | colors: { 90 | white: base.white, 91 | black: base.black, 92 | 93 | gray: scales.black60, 94 | lightGray: scales.black20, 95 | washedGray: scales.black05, 96 | 97 | red: base.red, 98 | lightRed: scales.red30, 99 | washedRed: scales.red05, 100 | 101 | yellow: base.yellow, 102 | lightYellow: scales.yellow30, 103 | washedYellow: scales.yellow10, 104 | 105 | green: base.green, 106 | lightGreen: scales.green30, 107 | washedGreen: scales.green10, 108 | 109 | blue: base.blue, 110 | lightBlue: scales.blue30, 111 | washedBlue: scales.blue10, 112 | 113 | none: "rgba(0,0,0,0)", 114 | 115 | scales: scales, 116 | util: util, 117 | }, 118 | fonts: { 119 | sans: `"Inter", "Inter UI", -apple-system, BlinkMacSystemFont, 'San Francisco', 'Helvetica Neue', Arial, sans-serif`, 120 | mono: `"Source Code Pro", "Roboto mono", "Courier New", monospace`, 121 | }, 122 | // font-size 123 | fontSizes: [ 124 | 12, // 0 125 | 14, // 1 126 | 16, // 2 127 | 20, // 3 128 | 24, // 4 129 | 32, // 5 130 | 48, // 6 131 | 64, // 7 132 | ], 133 | // font-weight 134 | fontWeights: { 135 | thin: 300, 136 | regular: 400, 137 | medium: 500, 138 | bold: 600, 139 | }, 140 | // line-height 141 | lineHeights: { 142 | min: 1.2, 143 | short: 1.33334, 144 | regular: 1.5, 145 | tall: 1.66667, 146 | }, 147 | // border, border-top, border-right, border-bottom, border-left 148 | borders: ["none", "1px solid"], 149 | // margin, margin-top, margin-right, margin-bottom, margin-left, padding, padding-top, padding-right, padding-bottom, padding-left, grid-gap, grid-column-gap, grid-row-gap 150 | space: [ 151 | 0, // 0 152 | 4, // 1 153 | 8, // 2 154 | 16, // 3 155 | 24, // 4 156 | 32, // 5 157 | 48, // 6 158 | 64, // 7 159 | 96, // 8 160 | ], 161 | // border-radius 162 | radii: [ 163 | 0, // 0 164 | 2, // 1 165 | 4, // 2 166 | 8, // 3 167 | ], 168 | // width, height, min-width, max-width, min-height, max-height 169 | sizes: [ 170 | 0, // 0 171 | 4, // 1 172 | 8, // 2 173 | 16, // 3 174 | 24, // 4 175 | 32, // 5 176 | 48, // 6 177 | 64, // 7 178 | 96, // 8 179 | ], 180 | // z-index 181 | zIndices: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 182 | breakpoints: ["768px", "1024px", "1440px", "2200px"], 183 | }; 184 | 185 | export type Theme = typeof light; 186 | export const styled = baseStyled as ThemedStyledInterface; 187 | -------------------------------------------------------------------------------- /DEVELOPMENT.md: -------------------------------------------------------------------------------- 1 | # Development 2 | 3 | ## Getting Started 4 | 5 | `npm install` 6 | 7 | `npm install -g typescript` if you have never install TS 8 | 9 | `npm run build` 10 | 11 | There are a few ways of making new components for Indigo. Let's cover some of the core patterns. 12 | 13 | ## Component Patterns 14 | 15 | ### Single Element Component with dynamic properties 16 | 17 | Creating a basic theme-aware component with dynamic properties from scratch. 18 | 19 | ```tsx 20 | import styled from "styled-components"; 21 | import css, { SystemStyleObject } from "@styled-system/css"; 22 | // commonStyle includes all commonly used styled-system props 23 | import { commonStyle, CommonStyleProps } from "./system/unions"; 24 | 25 | // Define property types and export typing 26 | export type LabelProps = CommonStyleProps & { 27 | gray?: boolean; 28 | bold?: boolean; 29 | mono?: boolean; 30 | }; 31 | 32 | // First, a we create a style object. Then, we pass it to css(), whcih converts values like fontSize:0 to fontSize:'12px'. The conversion is based on the theme. Css() returns a function that can be passed to styled.foo() as a StyleFn, like border, color, and flexbox imported from styled-system. This method is convinient because you don't have to pass the theme as a prop and write a bunch of template string functions for each dynamic property. We also assign prop defaults in the argument field. 33 | const style = ({ gray = false, bold = false, mono = false }: LabelProps) => 34 | css({ 35 | fontWeight: bold ? "bold" : "regular", 36 | color: gray ? "gray" : "black", 37 | fontFamily: mono ? "mono" : "sans", 38 | display: "block", 39 | lineHeight: "short", 40 | fontSize: 1, 41 | pointerEvents: "none", 42 | userSelect: "none", 43 | verticalAlign: "middle", 44 | width: "100%", 45 | } as SystemStyleObject); 46 | 47 | // Here, we define out component. Because we want this component to use an HTML