Skip to content

Commit

Permalink
Merge 047fd97 into 30fa3cc
Browse files Browse the repository at this point in the history
  • Loading branch information
ktravers authored Nov 12, 2024
2 parents 30fa3cc + 047fd97 commit f80dc0b
Show file tree
Hide file tree
Showing 3 changed files with 461 additions and 189 deletions.
2 changes: 1 addition & 1 deletion contributor-docs/migrating-to-css-modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ This guide outlines the steps to follow when refactoring Primer React components
- Add a feature flag to toggle the `sx` prop for controlled rollout (staff shipping). How it's used will be based on the implementation of the component. For most you'll be able to `useFeatureFlag` and toggle between components. For more complex styled components, you can use the utility `toggleStyledComponent` which will render based on the feature flag string provided.

```jsx
/* When there is an exisiting styled component, use the `toggleStyledComponent` utility. */
/* When there is an existing styled component, use the `toggleStyledComponent` utility. */
const StyledDiv = toggleStyledComponent(
'primer_react_css_modules_team',
'div',
Expand Down
244 changes: 244 additions & 0 deletions packages/react/src/TreeView/TreeView.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
.TreeViewRootUlStyles {
list-style: none;
padding: 0;
margin: 0;

/*
* WARNING: This is a performance optimization.
*
* We define styles for the tree items at the root level of the tree
* to avoid recomputing the styles for each item when the tree updates.
* We're sacraficing maintainability for performance because TreeView
* needs to be performant enough to handle large trees (thousands of items).
*
* This is intended to be a temporary solution until we can improve the
* performance of our styling patterns.
*
* Do NOT copy this pattern without understanding the tradeoffs.
* Do NOT reference PRIVATE_* classnames outside of this file.
*/
.PRIVATE_TreeView-item {
outline: none;

&:focus-visible > div,
&.focus-visible > div {
box-shadow: inset 0 0 0 2px var(--fgColor-accent, var(--color-accent-fg, #0969da));
@media (forced-colors: active) {
outline: 2px solid HighlightText;
outline-offset: -2;
}
}
&[data-has-leading-action] {
--has-leading-action: 1;
}
}

.PRIVATE_TreeView-item-container {
--level: 1; /* default level */
--toggle-width: 1rem; /* 16px */
--min-item-height: 2rem; /* 32px */
position: relative;
display: grid;
--leading-action-width: calc(var(--has-leading-action, 0) * 1.5rem);
--spacer-width: calc(calc(var(--level) - 1) * (var(--toggle-width) / 2));
grid-template-columns: var(--spacer-width) var(--leading-action-width) var(--toggle-width) 1fr;
grid-template-areas: 'spacer leadingAction toggle content';
width: 100%;
font-size: var(--base-size-14);
color: var(--fgColor-default, var(--color-fg-default, #1F2328));
border-radius: var(--borderRadius-medium);
cursor: pointer;

&:hover {
background-color: var(--control-transparent-bgColor-hover, var(--color-action-list-item-default-hover-bg, rgba(208, 215, 222, 0.32)));

@media (forced-colors: active) {
outline: 2px solid transparent;
outline-offset: -2px;
}
}

@media (pointer: coarse) {
--toggle-width: 1.5rem; /* 24px */
--min-item-height: 2.75rem; /* 44px */
}

&:has(.PRIVATE_TreeView-item-skeleton):hover {
background-color: transparent;
cursor: default;

@media (forced-colors: active) {
outline: none;
}
}
}

&[data-omit-spacer='true'] .PRIVATE_TreeView-item-container {
grid-template-columns: 0 0 0 1fr;
}

.PRIVATE_TreeView-item[aria-current='true'] > .PRIVATE_TreeView-item-container {
background-color: var(--control-transparent-bgColor-selected, var(--color-action-list-item-default-selected-bg, rgba(208, 215, 222, 0.24)));

/* Current item indicator */
&::after {
content: '';
position: absolute;
top: calc(50% - 0.75rem); /* 50% - 12px */
left: var(--base-size-8);
width: 0.25rem; /* 4px */
height: 1.5rem; /* 24px */
background-color: var(--fgColor-accent, var(--color-accent-fg, #0969da));
border-radius: var(--borderRadius-medium);

@media (forced-colors: active) {
background-color: HighlightText;
}
}
}

.PRIVATE_TreeView-item-toggle {
grid-area: toggle;
display: flex;
justify-content: center;
align-items: flex-start;
/* The toggle should appear vertically centered for single-line items, but remain at the top for items that wrap
across more lines. */
padding-top: calc(var(--min-item-height) / 2 - 12px / 2);
height: 100%;
color: var(---control-fgColor-placeholder,var(--fgColor-muted,var(--color-fg-muted,#656d76)));
}

.PRIVATE_TreeView-item-toggle--hover:hover {
background-color: var(--control-transparent-bgColor-hover, var(--color-tree-view-item-chevron-hover-bg, rgba(208, 215, 222, 0.32)));
}

.PRIVATE_TreeView-item-toggle--end {
border-top-left-radius: var(--borderRadius-medium);
border-bottom-left-radius: var(--borderRadius-medium);
}

.PRIVATE_TreeView-item-content {
grid-area: content;
display: flex;
height: 100%;
padding: 0 var(--base-size-8);
gap: var(--stack-gap-condensed);
line-height: var(--custom-line-height, var(--text-body-lineHeight-medium, 1.4285));
/* The dynamic top and bottom padding to maintain the minimum item height for single line items */
padding-top: calc((var(--min-item-height) - var(--custom-line-height, 1.3rem)) / 2);
padding-bottom: calc((var(--min-item-height) - var(--custom-line-height, 1.3rem)) / 2);
}

.PRIVATE_TreeView-item-content-text {
flex: 1 1 auto;
width: 0;
}

&[data-truncate-text='true'] .PRIVATE_TreeView-item-content-text {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}

&[data-truncate-text='false'] .PRIVATE_TreeView-item-content-text {
word-break: break-word;
}

.PRIVATE_TreeView-item-visual {
display: flex;
align-items: center;
color: var(---control-fgColor-placeholder,var(--fgColor-muted,var(--color-fg-muted,#656d76)));
/* The visual icons should appear vertically centered for single-line items, but remain at the top for items that wrap
across more lines. */
height: var(--custom-line-height, 1.3rem);
}

.PRIVATE_TreeView-item-leading-action {
display: flex;
color: var(---control-fgColor-placeholder,var(--fgColor-muted,var(--color-fg-muted,#656d76)));
grid-area: leadingAction;
}

.PRIVATE_TreeView-item-level-line {
width: 100%;
height: 100%;
border-right: 1px solid;

/*
* On devices without hover, the nesting indicator lines
* appear at all times.
*/
border-color: var(--borderColor-muted, var(--color-border-subtle, rgba(31, 35, 40, 0.15)));
}

/*
* On devices with :hover support, the nesting indicator lines
* fade in when the user mouses over the entire component,
* or when there's focus inside the component. This makes
* sure the component remains simple when not in use.
*/
@media (hover: hover) {
.PRIVATE_TreeView-item-level-line {
border-color: transparent;
}

&:hover .PRIVATE_TreeView-item-level-line,
&:focus-within .PRIVATE_TreeView-item-level-line {
border-color: var(--borderColor-muted, var(--color-border-subtle, rgba(31, 35, 40, 0.15)));
}
}

.PRIVATE_TreeView-directory-icon {
display: grid;
color: var(--treeViewItem-leadingVisual-bgColor-rest, var(--color-tree-view-item-chevron-directory-fill, #368cf9));
}

.PRIVATE_VisuallyHidden {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0;
}
}


.TreeViewSkeletonItemContainerStyle {
display: flex;
align-items: center;
column-gap: 0.5rem;
height: 2rem;

@media (pointer: coarse) {
height: 2.75rem;
}

&:nth-of-type(5n + 1) {
--tree-item-loading-width: 67%;
}

&:nth-of-type(5n + 2) {
--tree-item-loading-width: 47%;
}

&:nth-of-type(5n + 3) {
--tree-item-loading-width: 73%;
}

&:nth-of-type(5n + 4) {
--tree-item-loading-width: 64%;
}

&:nth-of-type(5n + 5) {
--tree-item-loading-width: 50%;
}
}

.TreeItemSkeletonTextStyles {
width: var(--tree-item-loading-width, 67%);
}
Loading

0 comments on commit f80dc0b

Please sign in to comment.