From 8abdad4a51ed5ca3d5f16f3ae6eca65c588897d6 Mon Sep 17 00:00:00 2001 From: Kurstyn Storms <84343098+KurstynStorms@users.noreply.github.com> Date: Thu, 5 May 2022 12:53:43 -0400 Subject: [PATCH 1/2] [PLAY-142] Visual Guidelines - Switch to React - Examples Template (#1849) * Rendered rough example in browser * Section separator between props and values * Added pills and continued to change styling * Fixed width of cards * Fixed flexitem alignment * Added title and body kits * Fixed more styling * Changed out background kit to fix border radius * Fixed border radius * Fixed border radius on other templates * Updated caption card * Fixed title margins * Corrected camelcase in pills * Three templates for visual guidelines * Fixed syntax error * Fixed syntax again * Testing client-side code example colorization * Use Rouge to format code examples * Template Complete Co-authored-by: Stephen Marshall --- .../app/controllers/pages_controller.rb | 14 +- .../VisualGuidelines/Examples/MaxWidth.tsx | 42 ++++++ .../VisualGuidelines/Examples/Positioning.tsx | 58 ++++++++ .../VisualGuidelines/Templates/Example.tsx | 132 ++++++++++++++++++ .../Templates/PropsValues.tsx | 60 ++++++++ .../components/VisualGuidelines/index.tsx | 19 ++- .../_border_radius_guidelines.scss | 5 +- .../pages/visual_guidelines_react.html.erb | 2 +- 8 files changed, 324 insertions(+), 8 deletions(-) create mode 100644 playbook-website/app/javascript/components/VisualGuidelines/Examples/MaxWidth.tsx create mode 100644 playbook-website/app/javascript/components/VisualGuidelines/Examples/Positioning.tsx create mode 100644 playbook-website/app/javascript/components/VisualGuidelines/Templates/Example.tsx create mode 100644 playbook-website/app/javascript/components/VisualGuidelines/Templates/PropsValues.tsx diff --git a/playbook-website/app/controllers/pages_controller.rb b/playbook-website/app/controllers/pages_controller.rb index c77a860f1f..152e241a6d 100755 --- a/playbook-website/app/controllers/pages_controller.rb +++ b/playbook-website/app/controllers/pages_controller.rb @@ -2,6 +2,7 @@ require "yaml" require "redcarpet" +require "rouge" require_relative "application_controller" @@ -76,7 +77,18 @@ def kit_show_react def principles; end # TODO: rename this method once all guidelines are completed - def visual_guidelines_react; end + def visual_guidelines_react + formatter = Rouge::Formatters::HTML.new + lexer = Rouge::Lexer.find("react") + kit_examples = {} + Dir.glob(Rails.root.join("app/views/pages/code_snippets/*.txt")).each do |example_path| + example_txt = File.read(example_path) + + formatted_example_txt = formatter.format(lexer.lex(example_txt)) + kit_examples[example_path.split("/").last.sub(".txt", "")] = formatted_example_txt + end + @kit_examples_json = kit_examples + end # TODO: remove this method once all guidelines are completed def visual_guidelines diff --git a/playbook-website/app/javascript/components/VisualGuidelines/Examples/MaxWidth.tsx b/playbook-website/app/javascript/components/VisualGuidelines/Examples/MaxWidth.tsx new file mode 100644 index 0000000000..98703e8d8f --- /dev/null +++ b/playbook-website/app/javascript/components/VisualGuidelines/Examples/MaxWidth.tsx @@ -0,0 +1,42 @@ +/* eslint-disable flowtype/no-types-missing-file-annotation */ + +import React from 'react' + +import { + Background, + Title, +} from 'playbook-ui' + +import Example from '../Templates/Example' + +const SIZES = ['xs', 'sm', 'md', 'lg', 'xl'] //TODO: investigate using types + +const MaxWidth = ({ example }: {example: string}) => ( + + {SIZES.map((size: string) => ( + + + {size.toUpperCase()} + + + ))} + +) + +export default MaxWidth diff --git a/playbook-website/app/javascript/components/VisualGuidelines/Examples/Positioning.tsx b/playbook-website/app/javascript/components/VisualGuidelines/Examples/Positioning.tsx new file mode 100644 index 0000000000..1a9774dc90 --- /dev/null +++ b/playbook-website/app/javascript/components/VisualGuidelines/Examples/Positioning.tsx @@ -0,0 +1,58 @@ +/* eslint-disable flowtype/no-types-missing-file-annotation */ + +import React from 'react' + +import { + Body, + Caption, + Card, +} from 'playbook-ui' + +import Example from '../Templates/Example' + +const ZINDEX = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] //TODO: investigate using types +const TOKENS = { + '$z_1': 100, + '$z_2': 200, + '$z_3': 300, + '$z_4': 400, + '$z_5': 500, + '$z_6': 600, + '$z_7': 700, + '$z_8': 800, + '$z_9': 900, + '$z_10': 1000, +} + +const Positioning = ({ example, tokensExample }: {example: string, tokensExample?: string}) => ( + + + +
+ {Object.keys(TOKENS).map((token) => ( + + {token} + {`value: ${TOKENS[token]}`} + + ))} +
+
+
+) + +export default Positioning diff --git a/playbook-website/app/javascript/components/VisualGuidelines/Templates/Example.tsx b/playbook-website/app/javascript/components/VisualGuidelines/Templates/Example.tsx new file mode 100644 index 0000000000..8b3904f341 --- /dev/null +++ b/playbook-website/app/javascript/components/VisualGuidelines/Templates/Example.tsx @@ -0,0 +1,132 @@ +/* eslint-disable react/no-danger */ +/* eslint-disable flowtype/no-types-missing-file-annotation */ + +import React from 'react' + +import { + Body, + Caption, + Card, + FlexItem, + SectionSeparator, + Title, +} from 'playbook-ui' + +import PropsValues from './PropsValues' + +type ExampleType = { + children?: React.ReactChild[] | React.ReactChild, + description?: string, + example?: string, + globalProps?: { [key: string]: string[] | number[] }, + title?: string, + tokens?: { [key: string]: string | number } +} + +const Example = ({ + children, + description, + example, + globalProps, + title, + tokens, +}: ExampleType): React.ReactElement => { + const parser = new DOMParser(), + parsedExample = parser.parseFromString(example, 'text/html'), + exampleHtml = parsedExample.body.innerHTML + + return ( +
+ {title && ( + + )} + {description && ( + <Body marginBottom="lg"> + {description} + </Body> + )} + { globalProps && ( + <React.Fragment> + <Title + marginBottom="xs" + marginTop="sm" + size={4} + tag="h4" + text="Global Props" + /> + <Body marginBottom="lg"> + {'Available in every kit. These are added globally as they are most flexible when developing.'} + </Body> + </React.Fragment> + )} + { tokens && ( + <React.Fragment> + <Title + marginBottom="xs" + marginTop="lg" + size={4} + tag="h4" + text="Tokens" + /> + <Body marginBottom="lg"> + {'Make your own styles using Playbook tokens to keep your site consistent.'} + </Body> + </React.Fragment> + )} + <Card + padding="none" + rounded + shadow="deeper" + > + {children && ( + <FlexItem> + <Card.Body> + <Caption + marginBottom="xs" + text="Visual Guide" + /> + { children } + </Card.Body> + <SectionSeparator + alignItems="center" + variant="card" + /> + </FlexItem> + )} + {globalProps && ( + <PropsValues {...globalProps} /> + )} + <Card + background="dark" + className="border_radius_flat" + dark + padding="none" + > + <Caption + marginLeft="md" + paddingBottom="none" + paddingTop="md" + text="EXAMPLE IN USE" + /> + <div className="pb--codeCopy"> + <pre + className="highlight pt_sm" + style={{ margin: '0px' }} + > + <span dangerouslySetInnerHTML={{ __html: exampleHtml }} /> + </pre> + </div> + </Card> + </Card> + </div> + ) +} + +export default Example diff --git a/playbook-website/app/javascript/components/VisualGuidelines/Templates/PropsValues.tsx b/playbook-website/app/javascript/components/VisualGuidelines/Templates/PropsValues.tsx new file mode 100644 index 0000000000..63e9148cf8 --- /dev/null +++ b/playbook-website/app/javascript/components/VisualGuidelines/Templates/PropsValues.tsx @@ -0,0 +1,60 @@ +/* eslint-disable flowtype/no-types-missing-file-annotation */ +// React Pure component - do not use state! + +// This template has sections Props, Values, and Example In Use space. +// This template does not have a Visual Guide section. + +import React from 'react' +import { Caption, Card, Flex, FlexItem, Pill, SectionSeparator } from 'playbook-ui' + +// type Props = {[key: string]: string | number} + +const PropsValues = (props: {[key: string]: string[] | number[]}): React.ReactElement => ( + <Flex + inline="flex-container" + justifyContent="spaceBetween" + orientation="row" + vertical="stretch" + > + { Object.keys(props).map((propKey: string) => ( + <React.Fragment key={propKey}> + <FlexItem flex={1}> + <Card.Body> + <Caption + marginBottom="sm" + text="Props" + /> + <Pill + text={propKey} + textTransform="none" + /> + </Card.Body> + </FlexItem> + <SectionSeparator + marginBottom="md" + marginTop="md" + orientation="vertical" + variant="card" + /> + <FlexItem flex={1}> + <Card.Body> + <Caption + marginBottom="sm" + text="Values" + /> + {props[propKey].map((propValue) => ( + <Pill + key={`${propKey}-${propValue}`} + text={propValue} + textTransform="none" + variant="warning" + /> + ))} + </Card.Body> + </FlexItem> + </React.Fragment> + ))} + </Flex> +) + +export default PropsValues diff --git a/playbook-website/app/javascript/components/VisualGuidelines/index.tsx b/playbook-website/app/javascript/components/VisualGuidelines/index.tsx index c8b64f273a..5d2b2ead0d 100644 --- a/playbook-website/app/javascript/components/VisualGuidelines/index.tsx +++ b/playbook-website/app/javascript/components/VisualGuidelines/index.tsx @@ -4,11 +4,20 @@ import React from 'react' import Colors from './Colors' +import MaxWidth from './Examples/MaxWidth' +import Positioning from './Examples/Positioning' -const VisualGuidelines = (): React.ReactElement => ( - <React.Fragment> - <Colors /> - </React.Fragment> -) +const VisualGuidelines = ({ examples }: {examples: {[key: string]: string}}): React.ReactElement => { + return ( + <React.Fragment> + <Colors /> + <MaxWidth example={examples.width_jsx} /> + <Positioning + example={examples.positioning_jsx} + tokensExample={examples.position_token} + /> + </React.Fragment> + ) +} export default VisualGuidelines diff --git a/playbook-website/app/javascript/site_styles/visual_guidelines/_border_radius_guidelines.scss b/playbook-website/app/javascript/site_styles/visual_guidelines/_border_radius_guidelines.scss index 977e1e5334..eda2c49626 100644 --- a/playbook-website/app/javascript/site_styles/visual_guidelines/_border_radius_guidelines.scss +++ b/playbook-website/app/javascript/site_styles/visual_guidelines/_border_radius_guidelines.scss @@ -40,4 +40,7 @@ @include border-example; border-radius: $border_radius_none; } -} \ No newline at end of file + &_flat { + border-radius: 0 0 6px 6px !important; + } +} diff --git a/playbook-website/app/views/pages/visual_guidelines_react.html.erb b/playbook-website/app/views/pages/visual_guidelines_react.html.erb index d0496cce45..4650ab7b1d 100644 --- a/playbook-website/app/views/pages/visual_guidelines_react.html.erb +++ b/playbook-website/app/views/pages/visual_guidelines_react.html.erb @@ -12,6 +12,6 @@ <% end %> <% end %> <%= pb_rails("background", props: { classname: "token-wrapper", background_color: "light", padding: "xl" }) do %> - <%= react_component("VisualGuidelines") %> + <%= react_component("VisualGuidelines", examples: @kit_examples_json) %> <% end %> </div> From b659f6b110da7d0eb837177cb4190dafac9c43c2 Mon Sep 17 00:00:00 2001 From: Gordon Hodanich <ghodanich@gmail.com> Date: Thu, 12 May 2022 15:38:20 -0400 Subject: [PATCH 2/2] Converted Colors partial to TSX --- .../VisualGuidelines/Colors/index.tsx | 52 +++++++- .../VisualGuidelines/Colors/variables.ts | 80 +++++++++++++ .../_colors.html.slim | 112 ------------------ 3 files changed, 131 insertions(+), 113 deletions(-) delete mode 100755 playbook-website/app/views/pages/visual_guidelines_partials/_colors.html.slim diff --git a/playbook-website/app/javascript/components/VisualGuidelines/Colors/index.tsx b/playbook-website/app/javascript/components/VisualGuidelines/Colors/index.tsx index d26e7dd651..86186da99f 100644 --- a/playbook-website/app/javascript/components/VisualGuidelines/Colors/index.tsx +++ b/playbook-website/app/javascript/components/VisualGuidelines/Colors/index.tsx @@ -7,7 +7,17 @@ import { Title } from 'playbook-ui' import Example from './Example' import { - TEXT_COLORS, + ACTIONS, + ACTIVE, + BACKGROUND, + BORDER, + CARDS, + CATEGORY, + DATA, + PRODUCTS, + SHADOW, + STATUS, + TEXT_COLORS } from './variables' const Colors = (): React.ReactElement => ( @@ -23,6 +33,46 @@ const Colors = (): React.ReactElement => ( colors={TEXT_COLORS} title="Text Colors" /> + <Example + colors={BACKGROUND} + title="Backgrounds" + /> + <Example + colors={CARDS} + title="Cards" + /> + <Example + colors={STATUS} + title="Status" + /> + <Example + colors={DATA} + title="Data" + /> + <Example + colors={ACTIONS} + title="Actions" + /> + <Example + colors={ACTIVE} + title="Active" + /> + <Example + colors={BORDER} + title="Border" + /> + <Example + colors={SHADOW} + title="Shadow" + /> + <Example + colors={PRODUCTS} + title="Product Colors" + /> + <Example + colors={CATEGORY} + title="Category Colors" + /> </React.Fragment> ) diff --git a/playbook-website/app/javascript/components/VisualGuidelines/Colors/variables.ts b/playbook-website/app/javascript/components/VisualGuidelines/Colors/variables.ts index 746fb403b0..b92b5cbf15 100644 --- a/playbook-website/app/javascript/components/VisualGuidelines/Colors/variables.ts +++ b/playbook-website/app/javascript/components/VisualGuidelines/Colors/variables.ts @@ -6,3 +6,83 @@ export const TEXT_COLORS = [ { name: 'Light Dk', variable: 'text_dk_light', dark: true }, { name: 'Lighter Dk', variable: 'text_dk_lighter', dark: true }, ] + export const BACKGROUND = [ + {name: "Bg Light", variable: "bg_light"}, + {name: "Bg Dark", variable: "bg_dark"}, + {name: "Bg Gradient", variable: "bg_gradient"} + ] + + export const CARDS = [ + {name: "Card Light", variable: "card_light"}, + {name: "Card Dark", variable: "card_dark", dark: true} + ] + + export const STATUS = [ + {name: "Success", variable: "success"}, + {name: "Warning", variable: "warning"}, + {name: "Error", variable: "error"}, + {name: "Info", variable: "info"}, + {name: "Neutral", variable: "neutral"} + ] + + export const DATA = [ + {name: "Data 1", variable: "data_1"}, + {name: "Data 2", variable: "data_2"}, + {name: "Data 3", variable: "data_3"}, + {name: "Data 4", variable: "data_4"}, + {name: "Data 5", variable: "data_5"}, + {name: "Data 6", variable: "data_6"}, + {name: "Data 7", variable: "data_7"}, + {name: "Data 8", variable: "data_8"} + ] + + export const ACTIONS = [ + {name: "Primary", variable: "primary_action"} + ] + + export const ACTIVE = [ + {name: "Active Light", variable: "active_light"}, + {name: "Active Dark", variable: "active_dark", dark: true} + ] + + export const BORDER = [ + {name: "Border Light", variable: "border_light"}, + {name: "Border Dark", variable: "border_dark", dark: true} + ] + + export const SHADOW = [ + {name: "Shadow", variable: "shadow"} + ] + + export const PRODUCTS = [ + {name: "Windows", variable: "windows"}, + {name: "Siding", variable: "siding"}, + {name: "Doors", variable: "doors"}, + {name: "Solar", variable: "solar"}, + {name: "Roofing", variable: "roofing"}, + {name: "Gutters", variable: "gutters"}, + {name: "Attic Insulation", variable: "insulation"} + ] + + export const CATEGORY = [ + {name: "Category 2", variable: "category_2"}, + {name: "Category 3", variable: "category_3"}, + {name: "Category 4", variable: "category_4"}, + {name: "Category 5", variable: "category_5"}, + {name: "Category 6", variable: "category_6"}, + {name: "Category 7", variable: "category_7"}, + {name: "Category 8", variable: "category_8"}, + {name: "Category 9", variable: "category_9"}, + {name: "Category 10", variable: "category_10"}, + {name: "Category 11", variable: "category_11"}, + {name: "Category 12", variable: "category_12"}, + {name: "Category 13", variable: "category_13"}, + {name: "Category 14", variable: "category_14"}, + {name: "Category 15", variable: "category_15"}, + {name: "Category 16", variable: "category_16"}, + {name: "Category 17", variable: "category_17"}, + {name: "Category 18", variable: "category_18"}, + {name: "Category 19", variable: "category_19"}, + {name: "Category 20", variable: "category_20"}, + {name: "Category 21", variable: "category_21"} + ] diff --git a/playbook-website/app/views/pages/visual_guidelines_partials/_colors.html.slim b/playbook-website/app/views/pages/visual_guidelines_partials/_colors.html.slim deleted file mode 100755 index ce4c23f01c..0000000000 --- a/playbook-website/app/views/pages/visual_guidelines_partials/_colors.html.slim +++ /dev/null @@ -1,112 +0,0 @@ -= pb_rails("title", props: { text: "Colors", tag: "h1", size: 1 }) - -// Text ---------------------------- -= render :partial => "pages/visual_guidelines_partials/pb_doc_color", - locals:{ title: "Text Colors", - usage: "Used for text", - colors: [{name: "Default", variable: "text_lt_default"}, - {name: "Light", variable: "text_lt_light"}, - {name: "Lighter", variable: "text_lt_lighter"}, - {name: "Default Dk", variable: "text_dk_default", dark: true}, - {name: "Light Dk", variable: "text_dk_light", dark: true}, - {name: "Lighter Dk", variable: "text_dk_lighter", dark: true}]} - -// Backgrounds --------------------- -= render :partial => "pages/visual_guidelines_partials/pb_doc_color", - locals:{ title: "Backgrounds", - usage: "Used for backgrounds", - colors: [{name: "Bg Light", variable: "bg_light"}, - {name: "Bg Dark", variable: "bg_dark"}, - {name: "Bg Gradient", variable: "bg_gradient"}]} - -// Cards --------------------------- -= render :partial => "pages/visual_guidelines_partials/pb_doc_color", - locals:{ title: "Cards", - usage: "Used for card backgrounds", - colors: [{name: "Card Light", variable: "card_light"}, - {name: "Card Dark", variable: "card_dark", dark: true}]} - -// Status -------------------------- -= render :partial => "pages/visual_guidelines_partials/pb_doc_color", - locals:{ title: "Status", - usage: "Used for status indicators", - colors: [{name: "Success", variable: "success"}, - {name: "Warning", variable: "warning"}, - {name: "Error", variable: "error"}, - {name: "Info", variable: "info"}, - {name: "Neutral", variable: "neutral"}]} - -// Data ---------------------------- -= render :partial => "pages/visual_guidelines_partials/pb_doc_color", - locals:{ title: "Data", - usage: "Used in graphs, charts and stats", - colors: [{name: "Data 1", variable: "data_1"}, - {name: "Data 2", variable: "data_2"}, - {name: "Data 3", variable: "data_3"}, - {name: "Data 4", variable: "data_4"}, - {name: "Data 5", variable: "data_5"}, - {name: "Data 6", variable: "data_6"}, - {name: "Data 7", variable: "data_7"}, - {name: "Data 8", variable: "data_8"}]} - -// Actions ------------------------- -= render :partial => "pages/visual_guidelines_partials/pb_doc_color", - locals:{ title: "Actions", - usage: "Used for links and action buttons", - colors: [{name: "Primary", variable: "primary_action"}]} - -// Active -------------------------- -= render :partial => "pages/visual_guidelines_partials/pb_doc_color", - locals:{ title: "Active", - usage: "Used for active or selected states", - colors: [{name: "Active Light", variable: "active_light"}, - {name: "Active Dark", variable: "active_dark", dark: true}]} - -// Border -------------------------- -= render :partial => "pages/visual_guidelines_partials/pb_doc_color", - locals:{ title: "Border", - colors: [{name: "Border Light", variable: "border_light"}, - {name: "Border Dark", variable: "border_dark", dark: true}]} - -// Shadow -------------------------- -= render :partial => "pages/visual_guidelines_partials/pb_doc_color", - locals:{ title: "Shadow", - colors: [{name: "Shadow", variable: "shadow"}]} - -// Products ------------------------ -= render :partial => "pages/visual_guidelines_partials/pb_doc_color", - locals:{ title: "Product Colors", - usage: "Used for specific product indicators", - colors: [{name: "Windows", variable: "windows"}, - {name: "Siding", variable: "siding"}, - {name: "Doors", variable: "doors"}, - {name: "Solar", variable: "solar"}, - {name: "Roofing", variable: "roofing"}, - {name: "Gutters", variable: "gutters"}, - {name: "Attic Insulation", variable: "insulation"}]} - -// Category ------------------------ -= render :partial => "pages/visual_guidelines_partials/pb_doc_color", - locals:{ title: "Category Colors", - usage: "Used for categorization", - colors: [{name: "Category 1", variable: "category_1"}, - {name: "Category 2", variable: "category_2"}, - {name: "Category 3", variable: "category_3"}, - {name: "Category 4", variable: "category_4"}, - {name: "Category 5", variable: "category_5"}, - {name: "Category 6", variable: "category_6"}, - {name: "Category 7", variable: "category_7"}, - {name: "Category 8", variable: "category_8"}, - {name: "Category 9", variable: "category_9"}, - {name: "Category 10", variable: "category_10"}, - {name: "Category 11", variable: "category_11"}, - {name: "Category 12", variable: "category_12"}, - {name: "Category 13", variable: "category_13"}, - {name: "Category 14", variable: "category_14"}, - {name: "Category 15", variable: "category_15"}, - {name: "Category 16", variable: "category_16"}, - {name: "Category 17", variable: "category_17"}, - {name: "Category 18", variable: "category_18"}, - {name: "Category 19", variable: "category_19"}, - {name: "Category 20", variable: "category_20"}, - {name: "Category 21", variable: "category_21"}]}