diff --git a/playbook-website/app/javascript/components/MainSidebar/MenuData/GuidelinesNavItems.ts b/playbook-website/app/javascript/components/MainSidebar/MenuData/GuidelinesNavItems.ts index 9303a1d3f7..da7e613fbd 100644 --- a/playbook-website/app/javascript/components/MainSidebar/MenuData/GuidelinesNavItems.ts +++ b/playbook-website/app/javascript/components/MainSidebar/MenuData/GuidelinesNavItems.ts @@ -63,6 +63,10 @@ export const VisualGuidelinesItems = [ name: "Hover", link: "/visual_guidelines/hover" }, + { + name: "Group Hover", + link: "/visual_guidelines/group_hover" + }, { name: "Text Align", link: "/visual_guidelines/text_align" diff --git a/playbook-website/app/javascript/components/VisualGuidelines/Examples/GroupHover.tsx b/playbook-website/app/javascript/components/VisualGuidelines/Examples/GroupHover.tsx new file mode 100644 index 0000000000..4e262da48b --- /dev/null +++ b/playbook-website/app/javascript/components/VisualGuidelines/Examples/GroupHover.tsx @@ -0,0 +1,49 @@ +/* eslint-disable flowtype/no-types-missing-file-annotation */ + +import React from 'react' + +import { + Card, + Title, +} from 'playbook-ui' + +import Example from '../Templates/Example' + +const GroupHoverDescription = () => ( + <> + You can hover over a kit and its children's hover affects will be applied. Check out {"our hover affects here."} + +) + +const GroupHover = ({ example }: {example: string}) => ( + } + example={example} + title="Group Hover" + > + + + <Title + alignSelf="center" + paddingY="lg" + text="I don't have any hover effect on me" + /> + <Title + alignSelf="center" + hover={{ scale: "lg"}} + text="I need to be hovered over directly" + /> + </Card> + </Example> +) + +export default GroupHover diff --git a/playbook-website/app/javascript/components/VisualGuidelines/index.tsx b/playbook-website/app/javascript/components/VisualGuidelines/index.tsx index 98356e6aa8..043d89d30a 100644 --- a/playbook-website/app/javascript/components/VisualGuidelines/index.tsx +++ b/playbook-website/app/javascript/components/VisualGuidelines/index.tsx @@ -18,6 +18,7 @@ import Cursor from "../VisualGuidelines/Examples/Cursor"; import FlexBox from "../VisualGuidelines/Examples/FlexBox"; import Position from "../VisualGuidelines/Examples/Position"; import Hover from "../VisualGuidelines/Examples/Hover"; +import GroupHover from "../VisualGuidelines/Examples/GroupHover"; import TextAlign from "../VisualGuidelines/Examples/TextAlign"; import Overflow from "./Examples/Overflow"; import Truncate from "./Examples/Truncate"; @@ -82,6 +83,8 @@ const VisualGuidelines = ({ return <VerticalAlign example={examples.vertical_align_jsx}/>; case "hover": return <Hover example={examples.hover_jsx}/>; + case "group_hover": + return <GroupHover example={examples.group_hover_jsx}/>; case "text_align": return <TextAlign example={examples.text_align_jsx} /> case "overflow": diff --git a/playbook-website/app/views/pages/code_snippets/group_hover_jsx.txt b/playbook-website/app/views/pages/code_snippets/group_hover_jsx.txt new file mode 100644 index 0000000000..6366242b5d --- /dev/null +++ b/playbook-website/app/views/pages/code_snippets/group_hover_jsx.txt @@ -0,0 +1,21 @@ +<Card + cursor="pointer" + groupHover +> + <Title + alignSelf="center" + groupHover + hover={{ scale: "lg"}} + text="If the card is hovered, I'm hovered too!" + /> + <Title + alignSelf="center" + paddingY="lg" + text="I don't have any hover effect on me" + /> + <Title + alignSelf="center" + hover={{ scale: "lg"}} + text="I need to be hovered over directly" + /> +</Card> diff --git a/playbook/app/pb_kits/playbook/utilities/_hover.scss b/playbook/app/pb_kits/playbook/utilities/_hover.scss index 853d835123..c5c6918709 100644 --- a/playbook/app/pb_kits/playbook/utilities/_hover.scss +++ b/playbook/app/pb_kits/playbook/utilities/_hover.scss @@ -1,51 +1,54 @@ @import "../tokens/exports/scale.module"; -@mixin hover-color-classes($colors-list) { - @each $name, $color in $colors-list { - .hover_background_#{"" + $name}:hover { - background-color: $color !important; - transition: background-color $transition-speed ease; - } - .hover_color_#{"" + $name}:hover { - color: $color !important; - transition: color $transition-speed ease; - } +@mixin hover-scale-classes($scales-list) { + @each $name, $scale in $scales-list { + .hover_#{"" + $name}:hover, + .group_hover:hover .group_hover.hover_#{"" + $name} { + transform: $scale; + transition: transform $transition-speed ease; } } - - @mixin hover-shadow-classes($shadows-list) { - @each $name, $shadow in $shadows-list { - .hover_#{"" + $name}:hover { - box-shadow: $shadow; - transition: box-shadow $transition-speed ease; - } +} + +@mixin hover-shadow-classes($shadows-list) { + @each $name, $shadow in $shadows-list { + .hover_#{"" + $name}:hover, + .group_hover:hover .group_hover.hover_#{"" + $name} { + box-shadow: $shadow; + transition: box-shadow $transition-speed ease; } } - - @mixin hover-scale-classes($scales-list) { - @each $name, $scale in $scales-list { - .hover_#{"" + $name}:hover { - transform: $scale; - transition: transform $transition-speed ease; - } +} + +@mixin hover-color-classes($colors-list) { + @each $name, $color in $colors-list { + .hover_background_#{"" + $name}:hover, + .group_hover:hover .group_hover.hover_background_#{"" + $name} { + background-color: $color !important; + transition: background-color $transition-speed ease; + } + .hover_color_#{"" + $name}:hover, + .group_hover:hover .group_hover.hover_color_#{"" + $name} { + color: $color !important; + transition: color $transition-speed ease; } } - - - @include hover-scale-classes($scales); - @include hover-shadow-classes($box_shadows); - @include hover-color-classes($product_colors); - @include hover-color-classes($status_colors); - @include hover-color-classes($data_colors); - @include hover-color-classes($shadow_colors); - @include hover-color-classes($colors); - @include hover-color-classes($interface_colors); - @include hover-color-classes($main_colors); - @include hover-color-classes($background_colors); - @include hover-color-classes($card_colors); - @include hover-color-classes($active_colors); - @include hover-color-classes($action_colors); - @include hover-color-classes($hover_colors); - @include hover-color-classes($border_colors); - @include hover-color-classes($text_colors); - @include hover-color-classes($category_colors); \ No newline at end of file +} + +@include hover-scale-classes($scales); +@include hover-shadow-classes($box_shadows); +@include hover-color-classes($product_colors); +@include hover-color-classes($status_colors); +@include hover-color-classes($data_colors); +@include hover-color-classes($shadow_colors); +@include hover-color-classes($colors); +@include hover-color-classes($interface_colors); +@include hover-color-classes($main_colors); +@include hover-color-classes($background_colors); +@include hover-color-classes($card_colors); +@include hover-color-classes($active_colors); +@include hover-color-classes($action_colors); +@include hover-color-classes($hover_colors); +@include hover-color-classes($border_colors); +@include hover-color-classes($text_colors); +@include hover-color-classes($category_colors); diff --git a/playbook/app/pb_kits/playbook/utilities/globalPropNames.mjs b/playbook/app/pb_kits/playbook/utilities/globalPropNames.mjs index d41b00be0b..217f976a8d 100644 --- a/playbook/app/pb_kits/playbook/utilities/globalPropNames.mjs +++ b/playbook/app/pb_kits/playbook/utilities/globalPropNames.mjs @@ -4,6 +4,7 @@ export default [ "right", "top", "hover", + "groupHover", "zIndex", "verticalAlign", "truncate", diff --git a/playbook/app/pb_kits/playbook/utilities/globalProps.ts b/playbook/app/pb_kits/playbook/utilities/globalProps.ts index 9dd67b7223..3f6e2f2f88 100644 --- a/playbook/app/pb_kits/playbook/utilities/globalProps.ts +++ b/playbook/app/pb_kits/playbook/utilities/globalProps.ts @@ -66,6 +66,10 @@ type Hover = Shadow & { scale?: "sm" | "md" | "lg" } +type GroupHover = { + groupHover?: boolean, +} + type JustifyContent = { justifyContent?: Alignment & Space } @@ -175,7 +179,7 @@ export type GlobalProps = AlignContent & AlignItems & AlignSelf & BorderRadius & Cursor & Dark & Display & DisplaySizes & Flex & FlexDirection & FlexGrow & FlexShrink & FlexWrap & JustifyContent & JustifySelf & LineHeight & Margin & MinWidth & MaxWidth & NumberSpacing & Order & Overflow & Padding & - Position & Shadow & TextAlign & Truncate & VerticalAlign & ZIndex & { hover?: string } & Top & Right & Bottom & Left; + Position & Shadow & TextAlign & Truncate & VerticalAlign & ZIndex & GroupHover & { hover?: string } & Top & Right & Bottom & Left; const getResponsivePropClasses = (prop: {[key: string]: string}, classPrefix: string) => { const keys: string[] = Object.keys(prop) @@ -209,6 +213,7 @@ const filterClassName = (value: string): string => { // Prop categories const PROP_CATEGORIES: {[key:string]: (props: {[key: string]: any}) => string} = { + groupHoverProps: ({ groupHover }: GroupHover ) => groupHover ? 'group_hover ' : '', hoverProps: ({ hover }: { hover?: Hover }) => { let css = ''; if (!hover) return css; diff --git a/playbook/lib/playbook/hover.rb b/playbook/lib/playbook/hover.rb index 769947b477..e3cf074d00 100644 --- a/playbook/lib/playbook/hover.rb +++ b/playbook/lib/playbook/hover.rb @@ -4,6 +4,7 @@ module Playbook module Hover def self.included(base) base.prop :hover + base.prop :group_hover, type: Playbook::Props::Boolean, default: false end def hover_options @@ -38,7 +39,8 @@ def hover_attributes def hover_props selected_props = hover_options.keys.select { |sk| try(sk) } - return nil unless selected_props.present? + + return nil if selected_props.nil? && group_hover.nil? responsive = selected_props.present? && try(selected_props.first).is_a?(::Hash) css = "" @@ -58,6 +60,7 @@ def hover_props end end + css += "group_hover " if group_hover css.strip unless css.blank? end end