Skip to content

Commit

Permalink
new expandable component (#4847)
Browse files Browse the repository at this point in the history
this pr creates completes this asana task:
https://app.asana.com/0/1200099998847559/1206422502609164/f and creates
an expandable component similar to notion toggles. it should:
1. display the expanded content just looks like the other content on the
page (ie no box border and no color)
2. make the alt_header inkable like a section title


we can use the following compoent to use it:

```
<expandable alt_header="add your info here">
add your content here
</expandable>
```
  • Loading branch information
mirnawong1 authored Feb 15, 2024
2 parents 0e5b35f + 0fa8cb4 commit fd60564
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 2 deletions.
2 changes: 1 addition & 1 deletion website/docs/docs/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ As a dbt user, your main focus will be on writing models (i.e. select queries) t
| Load seed files| Often in analytics, raw values need to be mapped to a more readable value (for example, converting a country-code to a country name) or enriched with static or infrequently changing data. These data sources, known as seed files, can be saved as a CSV file in your `project` and loaded into your data warehouse using the `seed` command. Read more about [Seeds](/docs/build/seeds).|
| Snapshot data | Often, records in a data source are mutable, in that they change over time. This can be difficult to handle in analytics if you want to reconstruct historic values. dbt provides a mechanism to snapshot raw data for a point in time, through use of [snapshots](/docs/build/snapshots).|

### Related docs
## Related docs

- [Quickstarts for dbt](/guides)
- [Best practice guides](/best-practices)
Expand Down
51 changes: 51 additions & 0 deletions website/src/components/expandable/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/* eslint-disable */

import React, { useState } from 'react';
import styles from './styles.module.css';

function slugify(text) {
return text.toString().toLowerCase()
.normalize('NFD') // Normalize to NFD Unicode form
.replace(/[\u0300-\u036f]/g, '') // Remove diacritics
.replace(/\s+/g, '-') // Replace spaces with -
.replace(/[^\w\-]+/g, '') // Remove all non-word chars
.replace(/\-\-+/g, '-') // Replace multiple - with single -
.replace(/^-+/, '') // Trim - from start
.replace(/-+$/, ''); // Trim - from end
}

function expandable({ children, alt_header = null }) {
if(!alt_header) { return null; }
const [isOn, setOn] = useState(false);
// generate a slug from the alt_header
const anchorId = slugify(alt_header);

const handleToggleClick = (event) => {
event.preventDefault();
setOn(current => !current);
};

return (
<div id={anchorId} className={`${styles.expandableContainer} ${styles.local} expandable-anchor anchor`}>
<a
href={`#${anchorId}`}
className={styles.link}
onClick={handleToggleClick}
role="button"
tabIndex="0"
>
<span className={`${styles.toggle} ${isOn ? styles.toggleDown : styles.toggleRight}`}></span>
&nbsp;
<span className={styles.headerText}>{alt_header}</span>
</a>
<div
style={{ display: isOn ? 'block' : 'none' }}
className={styles.body}
>
{children}
</div>
</div>
);
}

export default expandable;
86 changes: 86 additions & 0 deletions website/src/components/expandable/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
:local(.link) :local(.headerText) {
content: '';
color: black; /* Black text in normal mode */
text-decoration: none;
transition: text-decoration 0.3s; /* Smooth transition */
font-weight: 600;
margin-bottom: 20px;
}

:local(.link:hover) :local(.headerText),
:local(.link:focus) :local(.headerText) {
text-decoration: underline;
cursor: pointer;
}

:local(.toggle)::before {
content: '';
display: inline-block;
border: solid black; /* Arrow color */
border-width: 0 2px 2px 0; /* Adjust for 'boldness' */
padding: 3px; /* Adjust size */
transform: rotate(45deg); /* Initial right-pointing arrow */
transition: transform 0.3s; /* Smooth transition for toggle icon */
margin-right: 8px;
}

:local(.toggleDown)::before {
transform: rotate(225deg); /* Downward arrow */
}

:local(.toggleRight)::before {
transform: rotate(315deg); /* Right-pointing arrow */
}

:local(.toggle)::before {
border-color: rgb(253, 153, 83); /* Orange arrow color in light mode */
}

/* Adjusting for Light and Dark Modes */
:local(html[data-theme='dark'] .link), :local(html[data-theme='dark'] .headerText) {
color: white; /* White text in dark mode */
}

:local(html[data-theme='dark'] .toggle)::before {
border-color: white; /* White arrow in dark mode */
border-color: rgb(253, 153, 83);
}

.expandableContainer :local(.body) {
margin-top: 10px;
margin-left: .5em;
padding: 10px;
background-color: transparent;
}

:local(html[data-theme='dark'] .link),
:local(html[data-theme='dark'] .headerText) {
color: white; /* White text in dark mode */
}

:local(.body > p:last-child) {
margin-bottom: 0px;

}

:local(.link)::after {
content: "";
display: inline-block;
width: 12px;
height: 12px;
background-image: url('/img/copy.png');
background-size: contain;
background-repeat: no-repeat;
opacity: 0; /* Start with icon hidden */
transition: opacity 0.3s ease-in-out;
margin-left: 8px;
}

:local(.link:not(.toggleOpen)):hover::after {
opacity: 1; /* Only show icon on hover when toggle is not open */
}

.expandableContainer {
margin-bottom: 10px; /* Adjust this value as needed to create space */
}

2 changes: 2 additions & 0 deletions website/src/theme/MDXComponents/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import dbtEditor from '@site/src/components/dbt-editor';
import Icon from '@site/src/components/icon';
import Lifecycle from '@site/src/components/lifeCycle';
import detailsToggle from '@site/src/components/detailsToggle';
import expandable from '@site/src/components/expandable';

const MDXComponents = {
head: MDXHead,
Expand Down Expand Up @@ -94,5 +95,6 @@ const MDXComponents = {
Icon: Icon,
Lifecycle: Lifecycle,
detailsToggle: detailsToggle,
expandable: expandable,
};
export default MDXComponents;
2 changes: 1 addition & 1 deletion website/static/js/headerLinkCopy.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

// separating function from eventlistener to understand they are two separate things
function copyHeader () {
const headers = document.querySelectorAll("h2.anchor, h3.anchor");
const headers = document.querySelectorAll("h2.anchor, h3.anchor, .expandable-anchor.anchor");

headers.forEach((header) => {
header.style.cursor = "pointer";
Expand Down

0 comments on commit fd60564

Please sign in to comment.