-
Notifications
You must be signed in to change notification settings - Fork 11
feat(SectionGallery): add section gallery components #47
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
Merged
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
dbc2ca9
feat(SectionGallery): add section gallery components
kmcfaul 2148ad0
update sectiongallery from rebase
kmcfaul 68ec4a8
some further updates to piping SectionGallery
kmcfaul c3e64f9
fixing interactive content
kmcfaul d0c3a6b
remove console log
kmcfaul d1cb796
remove console log 2
kmcfaul 5162994
make optional props optional
kmcfaul File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| --- | ||
| import { SectionGallery as SectionGalleryBase } from './SectionGallery' | ||
|
|
||
| const { illustrations, section, galleryItemsData, placeholderText, countText, initialLayout, hasGridText, hasGridImages, hasListText, hasListImages } = Astro.props | ||
| --- | ||
|
|
||
| <SectionGalleryBase | ||
| illustrations={illustrations} | ||
| section={section} | ||
| galleryItemsData={galleryItemsData} | ||
| placeholderText={placeholderText} | ||
| countText={countText} | ||
| initialLayout={initialLayout} | ||
| hasGridText={hasGridText} | ||
| hasGridImages={hasGridImages} | ||
| hasListText={hasListText} | ||
| hasListImages={hasListImages} | ||
| client:only="react" | ||
| /> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| /* Toolbar styles */ | ||
| .ws-section-gallery .pf-v6-c-toolbar { | ||
| margin-block-end: var(--pf-t--global--spacer--md); | ||
| } | ||
|
|
||
| /* Avoid link styling on gallery/data list item names */ | ||
| .ws-section-gallery-item { | ||
| text-decoration: inherit; | ||
| color: inherit; | ||
| } | ||
|
|
||
| /* Ensure cards within a row stretch vertically to fill row height */ | ||
| .ws-section-gallery .pf-v6-c-card { | ||
| height: 100%; | ||
| } | ||
|
|
||
| /* Limit width for data list view only */ | ||
| .ws-section-gallery .pf-v6-c-data-list { | ||
| max-width: var(--pf-t--global--breakpoint--lg); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,111 @@ | ||
| import { useState } from 'react' | ||
|
|
||
| import { SectionGalleryToolbar } from './SectionGalleryToolbar' | ||
| import { SectionGalleryGridLayout } from './SectionGalleryGridLayout' | ||
| import { SectionGalleryListLayout } from './SectionGalleryListLayout' | ||
| import { snakeCase } from 'change-case' | ||
|
|
||
| import './SectionGallery.css' | ||
|
|
||
| export interface SectionGalleryItem { | ||
| /** Name of the gallery item. Should match the page name of the item for routing, or an item should provide a link property in the SectionGalleryItemData. */ | ||
| name: string | ||
| /** Image file import */ | ||
| img: any | ||
| /** Data of the gallery item */ | ||
| data: SectionGalleryItemData | ||
| } | ||
|
|
||
| export interface SectionGalleryItemData { | ||
| /** Path to the item illustration */ // TODO: remove if img method is fine | ||
| illustration: string | ||
| /** Summary text of the item */ | ||
| summary: string | ||
| /** Label included in the item footer. Choose from a preset or pass a custom label. */ | ||
| label?: 'beta' | 'demo' | 'deprecated' | ||
| /** Link to the item, relative to the section, e.g. "/{section}/{page}" */ | ||
| link?: string | ||
| } | ||
|
|
||
| interface SectionGalleryProps { | ||
| /** Collection of illustations for the gallery */ | ||
| illustrations?: any | ||
| /** Section where the gallery is located */ | ||
| section: string | ||
| /** Data of all gallery items */ | ||
| galleryItemsData: Record<string, SectionGalleryItemData> | ||
| /** Placeholder text for the gallery search input */ | ||
| placeholderText?: string | ||
| /** Text for the amount of gallery items */ | ||
| countText?: string | ||
| /** Starting layout for the gallery */ | ||
| initialLayout?: 'grid' | 'list' | ||
| /** Indicates the grid layout has item summary text */ | ||
| hasGridText?: boolean | ||
| /** Indicates the grid layout has item images */ | ||
| hasGridImages?: boolean | ||
| /** Indicates the list layout has item summary text */ | ||
| hasListText?: boolean | ||
| /** Indicates the list layout has item images */ | ||
| hasListImages?: boolean | ||
| } | ||
|
|
||
| export const SectionGallery = ({ | ||
| illustrations, | ||
| section, | ||
| galleryItemsData, | ||
| placeholderText, | ||
| countText, | ||
| initialLayout = 'grid', | ||
| hasGridText = false, | ||
| hasGridImages = false, | ||
| hasListText = false, | ||
| hasListImages = false, | ||
| }: SectionGalleryProps) => { | ||
| const [searchTerm, setSearchTerm] = useState('') | ||
| const [layoutView, setLayoutView] = useState(initialLayout) | ||
|
|
||
| const galleryItems: SectionGalleryItem[] = Object.entries(galleryItemsData) | ||
| .map(([galleryItem, galleryItemData]) => ({ | ||
| name: galleryItem, | ||
| img: illustrations ? illustrations[snakeCase(galleryItem)] : undefined, | ||
| data: galleryItemData, | ||
| })) | ||
| .sort((item1, item2) => item1.name.localeCompare(item2.name)) | ||
|
|
||
| const nonCharsRegex = /[^A-Z0-9]+/gi | ||
| const filteringTerm = searchTerm.replace(nonCharsRegex, '') | ||
| const filteredItems: SectionGalleryItem[] = galleryItems.filter((item) => | ||
| new RegExp(filteringTerm).test(item.name.replace(nonCharsRegex, '')), | ||
| ) | ||
|
|
||
| return ( | ||
| <div className="ws-section-gallery"> | ||
| <SectionGalleryToolbar | ||
| galleryItemCount={galleryItems.length} | ||
| searchTerm={searchTerm} | ||
| setSearchTerm={setSearchTerm} | ||
| layoutView={layoutView} | ||
| setLayoutView={setLayoutView} | ||
| placeholderText={placeholderText} | ||
| countText={countText} | ||
| /> | ||
| {layoutView === 'grid' && ( | ||
| <SectionGalleryGridLayout | ||
| section={section} | ||
| galleryItems={filteredItems} | ||
| hasGridText={hasGridText} | ||
| hasGridImages={hasGridImages} | ||
| /> | ||
| )} | ||
| {layoutView === 'list' && ( | ||
| <SectionGalleryListLayout | ||
| section={section} | ||
| galleryItems={filteredItems} | ||
| hasListText={hasListText} | ||
| hasListImages={hasListImages} | ||
| /> | ||
| )} | ||
| </div> | ||
| ) | ||
| } |
97 changes: 97 additions & 0 deletions
97
src/components/section-gallery/SectionGalleryGridLayout.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| import React from 'react' | ||
| import { | ||
| Gallery, | ||
| GalleryItem, | ||
| Card, | ||
| CardHeader, | ||
| CardTitle, | ||
| CardBody, | ||
| CardFooter, | ||
| Label, | ||
| Content, | ||
| } from '@patternfly/react-core' | ||
| import { SectionGalleryItem } from './SectionGallery' | ||
| import { sentenceCase } from 'change-case' | ||
| import { convertToReactComponent } from '@patternfly/ast-helpers' | ||
|
|
||
| interface SectionGalleryGridLayoutProps { | ||
| /** Section where the gallery is located */ | ||
| section: string | ||
| /** List of gallery items */ | ||
| galleryItems: SectionGalleryItem[] | ||
| /** Indicates the grid layout has item summary text */ | ||
| hasGridText: boolean | ||
| /** Indicates the grid layout has item images */ | ||
| hasGridImages: boolean | ||
| } | ||
|
|
||
| export const SectionGalleryGridLayout = ({ | ||
| section, | ||
| galleryItems, | ||
| hasGridText, | ||
| hasGridImages, | ||
| }: SectionGalleryGridLayoutProps) => ( | ||
| <Gallery hasGutter> | ||
| {galleryItems.map(({ name, img, data }, idx) => { | ||
| const itemLink = data.link || `/${section}/${name}` | ||
|
|
||
| //TODO: rethink how JSX / enriched content is passed to framework | ||
| const summaryNoLinks = data.summary.replace( | ||
| /<a[^>]*>([^<]+)<\/a>/gm, | ||
| '$1', | ||
| ) | ||
| const { code } = convertToReactComponent(`<>${summaryNoLinks}</>`) | ||
| const getSummaryComponent = new Function('React', code) | ||
|
|
||
| return ( | ||
| <GalleryItem span={4} key={idx}> | ||
| <Card id={name} key={idx} isClickable> | ||
| <CardHeader | ||
| selectableActions={{ | ||
| to: itemLink, | ||
| selectableActionId: `${name}-input`, | ||
| selectableActionAriaLabelledby: name, | ||
| name: `clickable-card-${idx}`, | ||
| }} | ||
| > | ||
| <CardTitle>{sentenceCase(name)}</CardTitle> | ||
| </CardHeader> | ||
| {(hasGridImages || hasGridText) && ( | ||
| <CardBody> | ||
| {hasGridImages && img && ( | ||
| <img src={img.src} alt={`${name} illustration`} /> // verify whether this img.src approach is correct | ||
| )} | ||
| {hasGridText && ( | ||
| <Content isEditorial> | ||
| <Content component="p"> | ||
| {getSummaryComponent(React)} | ||
| </Content> | ||
| </Content> | ||
| )} | ||
| </CardBody> | ||
| )} | ||
| {data.label && ( | ||
| <CardFooter> | ||
| {data.label === 'beta' && ( | ||
| <Label color="blue" isCompact> | ||
| Beta | ||
| </Label> | ||
| )} | ||
| {data.label === 'deprecated' && ( | ||
| <Label color="grey" isCompact> | ||
| Deprecated | ||
| </Label> | ||
| )} | ||
| {data.label === 'demo' && ( | ||
| <Label color="purple" isCompact> | ||
| Demo | ||
| </Label> | ||
| )} | ||
| </CardFooter> | ||
| )} | ||
| </Card> | ||
| </GalleryItem> | ||
| ) | ||
| })} | ||
| </Gallery> | ||
| ) | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.