Skip to content
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

SUL23-489: Places to study table. #148

Merged
merged 23 commits into from
Jun 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
29e5536
SUL23-489: Front end scaffolding for Places To Study table
imonroe Jun 17, 2024
368ae17
SUL23-489: added responsive tables and started adding data to table
jenbreese Jun 17, 2024
a0dccb7
SUL23-489: adding more details and fixup to mobile
jenbreese Jun 18, 2024
5bfb986
fixup
jenbreese Jun 18, 2024
b884813
Fix to the time and the open or close text
jenbreese Jun 18, 2024
9c56ac5
switched back to the double quotes
jenbreese Jun 19, 2024
9dec3b1
fixup to the hours positioning
jenbreese Jun 19, 2024
83cc643
Map through the features for each study place
imonroe Jun 19, 2024
cd3b555
fixup to alignement. Added commas.
jenbreese Jun 20, 2024
fa039ce
Fixed the comma and the feature background color
jenbreese Jun 20, 2024
4de3112
removed the async to get rid of error. Will replace the filtering aft…
jenbreese Jun 20, 2024
0738ccc
adding in the medium display. has a bug
jenbreese Jun 20, 2024
7374cd7
fixup to the md to lg design
jenbreese Jun 21, 2024
dce6c11
Table improvements
pookmish Jun 21, 2024
6b62cd6
fix up to the mobile view
jenbreese Jun 21, 2024
e22cfb6
Added filtering
pookmish Jun 24, 2024
95b4f43
Added back the th and hocus to the buttons.
jenbreese Jun 24, 2024
b45b34c
changed underlines to match design on hocus states
jenbreese Jun 24, 2024
d06f645
added rounded corner to select
jenbreese Jun 24, 2024
4057348
fixup to the med breakpoint layout to remove grid styles
jenbreese Jun 25, 2024
c9ae31d
fix to buttons and changed to grey on the toggle
jenbreese Jun 25, 2024
466e037
Use radio buttons instead of buttons
pookmish Jun 25, 2024
2bd4841
update github actions
pookmish Jun 25, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .github/workflows/build_lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ jobs:
LIBGUIDE_CLIENT_SECRET: ${{ secrets.LIBGUIDE_CLIENT_SECRET }}
NEXT_PUBLIC_DRUPAL_BASE_URL: ${{ secrets.NEXT_PUBLIC_DRUPAL_BASE_URL }}
NEXT_PUBLIC_SITE_NAME: ${{ secrets.NEXT_PUBLIC_SITE_NAME }}
DRUPAL_BASIC_AUTH: ${{ secrets.DRUPAL_BASIC_AUTH }}
DRUPAL_BASIC_AUTH_ADMIN: ${{ secrets.DRUPAL_BASIC_AUTH_ADMIN }}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Restore Cache
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: |
node_modules
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/label.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
pr-labeler:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- uses: codelytv/pr-size-labeler@v1
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/update-dev-test-branches.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
NEXT_PUBLIC_DRUPAL_BASE_URL: ${{ secrets.NEXT_PUBLIC_DRUPAL_BASE_URL }}
NEXT_IMAGE_DOMAIN: ${{ secrets.NEXT_IMAGE_DOMAIN }}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
ref: 1.x
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"export": "next build && next export",
"lint": "next lint && tsc",
"graphql": "DOTENV_CONFIG_PATH=./.env.local graphql-codegen --config codegen.ts -r dotenv/config",
"postinstall": "git config --local core.hooksPath .githooks/"
"postinstall": "git config --local core.hooksPath .githooks/; exit 0"
},
"dependencies": {
"@formkit/auto-animate": "^0.8.2",
Expand Down Expand Up @@ -42,6 +42,7 @@
"react-obfuscate": "^3.6.9",
"react-obfuscate-email": "^1.1.2",
"react-stately": "^3.31.1",
"react-super-responsive-table": "^5.2.3",
"react-tiny-oembed": "^1.1.0",
"sharp": "^0.33.4",
"tailwind-merge": "^2.3.0",
Expand Down
6 changes: 4 additions & 2 deletions src/components/paragraph/stanford-lists.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,8 @@ const getViewPagedItems = cache(async (viewId: string, displayId: string, contex
tags.push("views:stanford_person")
break

case "sul_study_places--study_places":
case 'sul_study_places--study_places':
case 'sul_study_places--study_places_table':
tags.push("views:sul_study_place")
break
}
Expand Down Expand Up @@ -204,7 +205,8 @@ const getViewPagedItems = cache(async (viewId: string, displayId: string, contex
items = graphqlResponse.stanfordPerson?.results as unknown as NodeUnion[]
break

case "sul_study_places--study_places":
case 'sul_study_places--study_places':
case 'sul_study_places--study_places_table':
graphqlResponse = await client.sulStudyPlaces()
items = graphqlResponse.sulStudyPlaces?.results as unknown as NodeUnion[]
break
Expand Down
144 changes: 70 additions & 74 deletions src/components/patterns/elements/select-list.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,14 @@
"use client";

import {useSelect, SelectOptionDefinition, SelectProvider, SelectValue} from '@mui/base/useSelect';
import {useOption} from '@mui/base/useOption';
import {
KeyboardEvent,
MouseEvent,
FocusEvent,
ReactNode,
RefObject,
useEffect,
useId,
useLayoutEffect,
useRef
} from "react";
import {ChevronDownIcon} from "@heroicons/react/20/solid";
import {useBoolean, useIsClient} from "usehooks-ts";
import useOutsideClick from "@/lib/hooks/useOutsideClick";
"use client"

import {useSelect, SelectOptionDefinition, SelectProvider, SelectValue} from "@mui/base/useSelect"
import {useOption} from "@mui/base/useOption"
import {KeyboardEvent, MouseEvent, FocusEvent, ReactNode, RefObject, useEffect, useId, useLayoutEffect, useRef} from "react"
import {ChevronDownIcon} from "@heroicons/react/20/solid"
import {useBoolean, useIsClient} from "usehooks-ts"
import useOutsideClick from "@/lib/hooks/useOutsideClick"

interface Props {
options: SelectOptionDefinition<string>[];
options: SelectOptionDefinition<string>[]
label?: string
ariaLabelledby?: string
defaultValue?: any
Expand All @@ -30,50 +20,50 @@ interface Props {

interface OptionProps {
rootRef: RefObject<HTMLUListElement>
children?: ReactNode;
value: string;
disabled?: boolean;
children?: ReactNode
value: string
disabled?: boolean
}

const renderSelectedValue = (value: SelectValue<string, boolean>, options: SelectOptionDefinition<string>[]) => {
// @mui/[email protected]
// @mui/[email protected]
if (Array.isArray(value)) {
return value.map(item =>
return value.map(item => (
<span
key={item}
className="block bg-archway text-white rounded p-5 mb-2 whitespace-nowrap overflow-hidden text-ellipsis max-w-full"
className="mb-2 block max-w-full overflow-hidden text-ellipsis whitespace-nowrap rounded bg-archway p-5 text-white"
>
{renderSelectedValue(item, options)}
</span>
);
))
}
const selectedOption = options.find((option) => option.value === value);
return selectedOption ? selectedOption.label : null;
const selectedOption = options.find(option => option.value === value)
return selectedOption ? selectedOption.label : null
}

function CustomOption(props: OptionProps) {
const {children, value, rootRef, disabled = false} = props;
const {getRootProps, highlighted, selected} = useOption({rootRef: rootRef, value, disabled, label: children});
const {id, ...otherProps}: { id: string } = getRootProps();
const {children, value, rootRef, disabled = false} = props
const {getRootProps, highlighted, selected} = useOption({rootRef: rootRef, value, disabled, label: children})
const {id, ...otherProps}: {id: string} = getRootProps()
const selectedStyles = "bg-archway text-white " + (highlighted ? "underline" : "")
const highlightedStyles = "bg-black-10 text-black underline"

useEffect(() => {
if (highlighted && id && rootRef?.current?.parentElement) {
const item = document.getElementById(id);
const item = document.getElementById(id)
if (item) {
const itemTop = item?.offsetTop;
const itemHeight = item?.offsetHeight;
const itemTop = item?.offsetTop
const itemHeight = item?.offsetHeight
const parentScrollTop = rootRef.current.parentElement.scrollTop
const parentHeight = rootRef.current.parentElement.offsetHeight;
const parentHeight = rootRef.current.parentElement.offsetHeight

if (itemTop < parentScrollTop) {
rootRef.current.parentElement.scrollTop = itemTop;
rootRef.current.parentElement.scrollTop = itemTop
}

if ((itemTop + itemHeight) > parentScrollTop + parentHeight) {
rootRef.current.parentElement.scrollTop = itemTop - parentHeight + itemHeight;
if (itemTop + itemHeight > parentScrollTop + parentHeight) {
rootRef.current.parentElement.scrollTop = itemTop - parentHeight + itemHeight
}
}
}
Expand All @@ -83,90 +73,96 @@ function CustomOption(props: OptionProps) {
<li
{...otherProps}
id={id}
className={"m-0 mb-2 py-2 px-10 cursor-pointer hocus:underline overflow-hidden " + (selected ? selectedStyles : (highlighted ? highlightedStyles : "hocus:bg-black-10 hocus:text-black"))}
className={"m-0 mb-2 cursor-pointer overflow-hidden px-10 py-2 hocus:underline " + (selected ? selectedStyles : highlighted ? highlightedStyles : "hocus:bg-black-10 hocus:text-black")}
>
{children}
</li>
);
)
}

const SelectList = ({options, label, multiple, ariaLabelledby, ...props}: Props) => {
const labelId = useId();
const labeledBy = ariaLabelledby ?? labelId;
const listboxRef = useRef<HTMLUListElement>(null);
const {value: listboxVisible, setFalse: hideListbox, setValue: setListBoxVisible} = useBoolean(false);
const labelId = useId()
const labeledBy = ariaLabelledby ?? labelId
const listboxRef = useRef<HTMLUListElement>(null)
const {value: listboxVisible, setFalse: hideListbox, setValue: setListBoxVisible} = useBoolean(false)
const outsideClickProps = useOutsideClick(hideListbox)
const isClient = useIsClient();
const isClient = useIsClient()

const {getButtonProps, getListboxProps, contextValue, value} = useSelect<string, boolean>({
listboxRef,
onOpenChange: setListBoxVisible,
open: listboxVisible,
multiple,
...props
});
...props,
})

useEffect(() => listboxRef.current?.focus(), [listboxVisible]);
useEffect(() => listboxRef.current?.focus(), [listboxVisible])

useLayoutEffect(() => {
const parentContainer = listboxRef.current?.parentElement?.getBoundingClientRect();
const parentContainer = listboxRef.current?.parentElement?.getBoundingClientRect()
if (parentContainer && (parentContainer.bottom > window.innerHeight || parentContainer.top < 0)) {
listboxRef.current?.parentElement?.scrollIntoView({behavior: "smooth", block: "end", inline: "nearest"});
listboxRef.current?.parentElement?.scrollIntoView({behavior: "smooth", block: "end", inline: "nearest"})
}
}, [listboxVisible, value])

const optionChosen = (multiple && value) ? value.length > 0 : !!value;

const optionChosen = multiple && value ? value.length > 0 : !!value

if (!isClient) return null;
if (!isClient) return null

return (
<div className="relative h-fit" {...outsideClickProps}>
<div
className="relative h-fit"
{...outsideClickProps}
>
<button
{...getButtonProps()}
className="w-full border border-black-40 rounded text-left p-5"
className="w-full rounded-full border border-black-40 p-5 pl-15 text-left"
aria-labelledby={labeledBy}
>
<div className="flex justify-between flex-wrap">
{label &&
<div className={"relative " + (optionChosen ? "text-m0 top-[-15px] w-full" : "text-m0")}>
<div id={labelId} className="bg-white w-fit px-5">
<div className="flex flex-wrap justify-between">
{label && (
<div className={"relative " + (optionChosen ? "top-[-15px] w-full text-m0" : "text-m0")}>
<div
id={labelId}
className="w-fit bg-white px-5"
>
{label}
</div>
</div>
}
{optionChosen &&
<div className="overflow-hidden max-w-[calc(100%-30px)]">
{renderSelectedValue(value, options)}
</div>
}
)}
{optionChosen && <div className="max-w-[calc(100%-30px)] overflow-hidden">{renderSelectedValue(value, options)}</div>}

<ChevronDownIcon width={20} className="flex-shrink-0"/>
<ChevronDownIcon
width={20}
className="flex-shrink-0"
/>
</div>
</button>

<div
className={"absolute z-[10] w-full top-full left-0 max-h-[300px] pb-5 overflow-y-scroll shadow-lg border border-black-20 bg-white " + (listboxVisible ? '' : 'hidden')}>
<div className={"absolute left-0 top-full z-[10] max-h-[300px] w-full overflow-y-scroll border border-black-20 bg-white pb-5 shadow-lg " + (listboxVisible ? "" : "hidden")}>
<ul
{...getListboxProps()}
className={"list-unstyled " + (listboxVisible ? '' : 'hidden')}
className={"list-unstyled " + (listboxVisible ? "" : "hidden")}
aria-hidden={!listboxVisible}
aria-labelledby={labeledBy}
>
<SelectProvider value={contextValue}>
{options.map((option) => {
{options.map(option => {
return (
<CustomOption key={option.value} value={option.value} rootRef={listboxRef}>
<CustomOption
key={option.value}
value={option.value}
rootRef={listboxRef}
>
{option.label}
</CustomOption>
);
)
})}
</SelectProvider>
</ul>
</div>
</div>
);
)
}


export default SelectList;
export default SelectList
Loading
Loading