-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NavigationTabs Styling #2508
base: feature/tabs
Are you sure you want to change the base?
NavigationTabs Styling #2508
Changes from 38 commits
fbd5b24
62b657d
1a8410b
808642b
dda6285
4d233ce
fa9178e
4bca67f
ba21c38
af4523a
a40844e
88e86c7
aba7023
68c6f33
b1e8976
312f738
7e64d30
cc70d83
91c6aa9
d4db4b0
ed9f866
cf0dc05
30b3839
fd54ec2
67146d5
9f6e16b
27c3540
ca44911
cd941b2
b1f1d38
1031f0a
d2f791e
8a7b2a5
4dfe2b7
b21c0cb
6f93797
9f8b37e
0cdf1bd
b8c8ad6
476de45
b430e63
4cef4a4
296441b
28d53d3
9c4fa3d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@khanacademy/wonder-blocks-tabs": minor | ||
--- | ||
|
||
NavigationTabs: Update styles to handle different scenarios |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,4 +1,4 @@ | ||||||
import * as React from "react"; | ||||||
Check warning on line 1 in .storybook/preview.tsx
|
||||||
import wonderBlocksTheme from "./wonder-blocks-theme"; | ||||||
import {Decorator} from "@storybook/react"; | ||||||
import {semanticColor} from "@khanacademy/wonder-blocks-tokens"; | ||||||
|
@@ -115,9 +115,42 @@ | |||||
); | ||||||
}; | ||||||
|
||||||
/** | ||||||
* Wraps a story with `<div dir="rtl">` so it is shown in rtl mode. | ||||||
*/ | ||||||
const withLanguageDirection: Decorator = (Story, context) => { | ||||||
if (context.globals.direction === "rtl") { | ||||||
return ( | ||||||
<div dir="rtl"> | ||||||
<Story /> | ||||||
</div> | ||||||
) | ||||||
} else { | ||||||
return <Story /> | ||||||
} | ||||||
} | ||||||
|
||||||
/** | ||||||
* Wraps a story with styling that simulates [zoom](https://developer.mozilla.org/en-US/docs/Web/CSS/zoom). | ||||||
* | ||||||
* Note: It is still important to test with real browser zoom in different | ||||||
* browsers. For example, using the CSS zoom property in Safari looks a bit | ||||||
* different than when you zoom in the browser. | ||||||
*/ | ||||||
const withZoom: Decorator = (Story, context) => { | ||||||
if (context.globals.zoom) { | ||||||
return ( | ||||||
<div style={{ zoom: context.globals.zoom }}> | ||||||
<Story /> | ||||||
</div> | ||||||
) | ||||||
} | ||||||
return <Story /> | ||||||
} | ||||||
|
||||||
const preview: Preview = { | ||||||
parameters, | ||||||
decorators: [withThemeSwitcher], | ||||||
decorators: [withThemeSwitcher, withLanguageDirection, withZoom], | ||||||
globalTypes: { | ||||||
// Allow the user to select a theme from the toolbar. | ||||||
theme: { | ||||||
|
@@ -143,6 +176,48 @@ | |||||
dynamicTitle: true, | ||||||
}, | ||||||
}, | ||||||
direction: { | ||||||
description: "The language direction to use", | ||||||
toolbar: { | ||||||
title: "Language Direction", | ||||||
icon: "globe", | ||||||
items: [ | ||||||
{ | ||||||
value: "ltr", | ||||||
icon: "arrowrightalt", | ||||||
title: "Left to Right", | ||||||
}, | ||||||
{ | ||||||
value: "rtl", | ||||||
icon: "arrowleftalt", | ||||||
title: "Right to Left", | ||||||
}, | ||||||
], | ||||||
dynamicTitle: true, | ||||||
}, | ||||||
}, | ||||||
zoom: { | ||||||
description: "Preset zoom level", | ||||||
toolbar: { | ||||||
title: "Zoom Presets", | ||||||
icon: "zoom", | ||||||
items: [ | ||||||
{ | ||||||
// undefined so the there is no zoom value set | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: extra word?
Suggested change
|
||||||
value: undefined, | ||||||
title: "default", | ||||||
}, | ||||||
{ | ||||||
value: "2", | ||||||
title: "200%", | ||||||
}, | ||||||
{ | ||||||
value: "4", | ||||||
title: "400%", | ||||||
}, | ||||||
], | ||||||
}, | ||||||
} | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||
}, | ||||||
|
||||||
tags: ["autodocs"], | ||||||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -5,7 +5,9 @@ import {StyleSheet} from "aphrodite"; | |||||||||||||||||||||||||||||
import {addStyle} from "@khanacademy/wonder-blocks-core"; | ||||||||||||||||||||||||||||||
import { | ||||||||||||||||||||||||||||||
border, | ||||||||||||||||||||||||||||||
breakpoint, | ||||||||||||||||||||||||||||||
semanticColor, | ||||||||||||||||||||||||||||||
sizing, | ||||||||||||||||||||||||||||||
spacing, | ||||||||||||||||||||||||||||||
} from "@khanacademy/wonder-blocks-tokens"; | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
|
@@ -14,6 +16,7 @@ import {LabelLarge} from "@khanacademy/wonder-blocks-typography"; | |||||||||||||||||||||||||||||
const StyledTable = addStyle("table"); | ||||||||||||||||||||||||||||||
const StyledTh = addStyle("th"); | ||||||||||||||||||||||||||||||
const StyledTd = addStyle("td"); | ||||||||||||||||||||||||||||||
const StyledUl = addStyle("ul"); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
type Variant = {name: string; props: StrictArgs}; | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
|
@@ -22,7 +25,7 @@ type Props = { | |||||||||||||||||||||||||||||
* The children as a function that receives the state props used to render | ||||||||||||||||||||||||||||||
* each variant of the component. | ||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||
children: (props: any) => React.ReactNode; | ||||||||||||||||||||||||||||||
children: (props: any, name: string) => React.ReactNode; | ||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||
* The categories to display in the table as columns. | ||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||
|
@@ -31,59 +34,125 @@ type Props = { | |||||||||||||||||||||||||||||
* The states to display in the table as rows. | ||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||
columns: Array<Variant>; | ||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||
* The layout for AllVariants. | ||||||||||||||||||||||||||||||
* - `responsive`: variants will be displayed in a table at larger screen | ||||||||||||||||||||||||||||||
* sizes and in a list at smaller screen sizes | ||||||||||||||||||||||||||||||
* - `list`: variants will always be displayed in a list | ||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||
layout?: "responsive" | "list"; | ||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||
* A table that displays all possible variants of a component. | ||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||
export function AllVariants({children, columns, rows}: Props) { | ||||||||||||||||||||||||||||||
export function AllVariants(props: Props) { | ||||||||||||||||||||||||||||||
const {children, rows, columns, layout = "responsive"} = props; | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
return ( | ||||||||||||||||||||||||||||||
<StyledTable style={styles.table}> | ||||||||||||||||||||||||||||||
<thead> | ||||||||||||||||||||||||||||||
<tr> | ||||||||||||||||||||||||||||||
<StyledTh style={styles.cell}> | ||||||||||||||||||||||||||||||
<LabelLarge>Category / State</LabelLarge> | ||||||||||||||||||||||||||||||
</StyledTh> | ||||||||||||||||||||||||||||||
{columns.map((col, index) => ( | ||||||||||||||||||||||||||||||
<StyledTh key={index} scope="col" style={styles.cell}> | ||||||||||||||||||||||||||||||
<LabelLarge>{col.name}</LabelLarge> | ||||||||||||||||||||||||||||||
</StyledTh> | ||||||||||||||||||||||||||||||
))} | ||||||||||||||||||||||||||||||
</tr> | ||||||||||||||||||||||||||||||
</thead> | ||||||||||||||||||||||||||||||
<tbody> | ||||||||||||||||||||||||||||||
{rows.map((row, idx) => ( | ||||||||||||||||||||||||||||||
<tr key={idx}> | ||||||||||||||||||||||||||||||
<StyledTh scope="row" style={styles.cell}> | ||||||||||||||||||||||||||||||
<LabelLarge>{row.name}</LabelLarge> | ||||||||||||||||||||||||||||||
</StyledTh> | ||||||||||||||||||||||||||||||
{columns.map((col) => ( | ||||||||||||||||||||||||||||||
<StyledTd | ||||||||||||||||||||||||||||||
key={col.name} | ||||||||||||||||||||||||||||||
style={[ | ||||||||||||||||||||||||||||||
styles.cell, | ||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||
border: `${border.width.hairline}px dashed ${semanticColor.border.primary}`, | ||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||
]} | ||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||
{children({ | ||||||||||||||||||||||||||||||
...row.props, | ||||||||||||||||||||||||||||||
...col.props, | ||||||||||||||||||||||||||||||
})} | ||||||||||||||||||||||||||||||
</StyledTd> | ||||||||||||||||||||||||||||||
<> | ||||||||||||||||||||||||||||||
{layout === "responsive" && ( | ||||||||||||||||||||||||||||||
<StyledTable style={[styles.table]}> | ||||||||||||||||||||||||||||||
<thead> | ||||||||||||||||||||||||||||||
<tr> | ||||||||||||||||||||||||||||||
<StyledTh style={styles.cell}> | ||||||||||||||||||||||||||||||
<LabelLarge>Category / State</LabelLarge> | ||||||||||||||||||||||||||||||
</StyledTh> | ||||||||||||||||||||||||||||||
{columns.map((col, index) => ( | ||||||||||||||||||||||||||||||
<StyledTh | ||||||||||||||||||||||||||||||
key={index} | ||||||||||||||||||||||||||||||
scope="col" | ||||||||||||||||||||||||||||||
style={styles.cell} | ||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||
<LabelLarge>{col.name}</LabelLarge> | ||||||||||||||||||||||||||||||
</StyledTh> | ||||||||||||||||||||||||||||||
))} | ||||||||||||||||||||||||||||||
</tr> | ||||||||||||||||||||||||||||||
</thead> | ||||||||||||||||||||||||||||||
<tbody> | ||||||||||||||||||||||||||||||
{rows.map((row, idx) => ( | ||||||||||||||||||||||||||||||
<tr key={idx}> | ||||||||||||||||||||||||||||||
<StyledTh scope="row" style={styles.cell}> | ||||||||||||||||||||||||||||||
<LabelLarge>{row.name}</LabelLarge> | ||||||||||||||||||||||||||||||
</StyledTh> | ||||||||||||||||||||||||||||||
{columns.map((col) => ( | ||||||||||||||||||||||||||||||
<StyledTd | ||||||||||||||||||||||||||||||
key={col.name} | ||||||||||||||||||||||||||||||
style={[ | ||||||||||||||||||||||||||||||
styles.cell, | ||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||
border: `${border.width.hairline}px dashed ${semanticColor.border.primary}`, | ||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||
]} | ||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||
{children( | ||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||
...row.props, | ||||||||||||||||||||||||||||||
...col.props, | ||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||
`${row.name} ${col.name}`, | ||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh interesting, I just did something super similar in #2509! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice!! I was also addressing a11y warnings in the new stories! I see in #2509 we add |
||||||||||||||||||||||||||||||
)} | ||||||||||||||||||||||||||||||
</StyledTd> | ||||||||||||||||||||||||||||||
))} | ||||||||||||||||||||||||||||||
</tr> | ||||||||||||||||||||||||||||||
))} | ||||||||||||||||||||||||||||||
</tr> | ||||||||||||||||||||||||||||||
))} | ||||||||||||||||||||||||||||||
</tbody> | ||||||||||||||||||||||||||||||
</StyledTable> | ||||||||||||||||||||||||||||||
</tbody> | ||||||||||||||||||||||||||||||
</StyledTable> | ||||||||||||||||||||||||||||||
)} | ||||||||||||||||||||||||||||||
<StyledUl | ||||||||||||||||||||||||||||||
style={[ | ||||||||||||||||||||||||||||||
styles.list, | ||||||||||||||||||||||||||||||
layout === "responsive" && styles.listResponsive, | ||||||||||||||||||||||||||||||
]} | ||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||
{rows.map((row) => { | ||||||||||||||||||||||||||||||
return columns.map((column) => { | ||||||||||||||||||||||||||||||
return ( | ||||||||||||||||||||||||||||||
<li key={`${row.name} ${column.name}`}> | ||||||||||||||||||||||||||||||
<LabelLarge> | ||||||||||||||||||||||||||||||
Column: {column.name}, Row: {row.name} | ||||||||||||||||||||||||||||||
</LabelLarge> | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
<div | ||||||||||||||||||||||||||||||
style={{ | ||||||||||||||||||||||||||||||
padding: sizing.size_100, | ||||||||||||||||||||||||||||||
marginBlock: sizing.size_100, | ||||||||||||||||||||||||||||||
border: `${border.width.hairline}px dashed ${semanticColor.border.primary}`, | ||||||||||||||||||||||||||||||
}} | ||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion: It would be great switching to
Suggested change
Expanding on this, the styles could be moved to the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the reminder! Updated :) |
||||||||||||||||||||||||||||||
{children( | ||||||||||||||||||||||||||||||
{...column.props, ...row.props}, | ||||||||||||||||||||||||||||||
`${row.name} ${column.name}`, | ||||||||||||||||||||||||||||||
)} | ||||||||||||||||||||||||||||||
</div> | ||||||||||||||||||||||||||||||
</li> | ||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||
})} | ||||||||||||||||||||||||||||||
</StyledUl> | ||||||||||||||||||||||||||||||
</> | ||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
const styles = StyleSheet.create({ | ||||||||||||||||||||||||||||||
table: { | ||||||||||||||||||||||||||||||
borderCollapse: "collapse", | ||||||||||||||||||||||||||||||
textAlign: "left", | ||||||||||||||||||||||||||||||
[breakpoint.mediaQuery.smOrSmaller]: { | ||||||||||||||||||||||||||||||
display: "none", | ||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||
list: { | ||||||||||||||||||||||||||||||
margin: 0, | ||||||||||||||||||||||||||||||
padding: 0, | ||||||||||||||||||||||||||||||
listStyle: "none", | ||||||||||||||||||||||||||||||
display: "flex", | ||||||||||||||||||||||||||||||
flexDirection: "column", | ||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||
listResponsive: { | ||||||||||||||||||||||||||||||
[breakpoint.mediaQuery.mdOrLarger]: { | ||||||||||||||||||||||||||||||
display: "none", | ||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||
cell: { | ||||||||||||||||||||||||||||||
margin: spacing.medium_16, | ||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import React from "react"; | ||
import type {StrictArgs} from "@storybook/react"; | ||
import {StyleSheet} from "aphrodite"; | ||
import {View} from "@khanacademy/wonder-blocks-core"; | ||
import {LabelLarge} from "@khanacademy/wonder-blocks-typography"; | ||
import {sizing} from "@khanacademy/wonder-blocks-tokens"; | ||
|
||
type Props = { | ||
scenarios: {name: string; props: StrictArgs}[]; | ||
children: (props: any, name: string) => React.ReactNode; | ||
}; | ||
|
||
/** | ||
* Useful for stories that show different scenarios. | ||
* | ||
* Normally, ScenariosLayout is used for different cases at rest state. | ||
*/ | ||
export const ScenariosLayout = (props: Props) => { | ||
const {scenarios, children} = props; | ||
return ( | ||
<View style={styles.container}> | ||
{scenarios.map((scenario) => { | ||
return ( | ||
<View key={scenario.name} style={styles.scenario}> | ||
<LabelLarge>{scenario.name}</LabelLarge> | ||
{children(scenario.props, scenario.name)} | ||
</View> | ||
); | ||
})} | ||
</View> | ||
); | ||
}; | ||
|
||
const styles = StyleSheet.create({ | ||
container: { | ||
gap: sizing.size_200, | ||
alignItems: "flex-start", | ||
}, | ||
scenario: { | ||
gap: sizing.size_100, | ||
maxWidth: "100%", | ||
}, | ||
}); |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. praise: This is super useful! |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export const rtlText = "هذا الرابط مكتوب باللغة العربية"; | ||
export const longText = | ||
"Lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod tempor incididunt ut labore et dolore magna aliqua"; | ||
export const longTextWithNoWordBreak = | ||
"Loremipsumdolorsitametconsecteturadipiscingelitseddoeiusmodtemporincididuntutlaboreetdoloremagnaaliqua"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was trying to find a way for us to easily configure a story to be a specific zoom level so we can have some Chromatic tests covering those cases too. I came across the CSS zoom property to control magnification