Skip to content

Commit

Permalink
feat(vital-section): Add examples page, address PR feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
VancheeZze committed May 19, 2023
1 parent 74f7c0c commit 7c1aa40
Show file tree
Hide file tree
Showing 18 changed files with 447 additions and 62 deletions.
1 change: 1 addition & 0 deletions packages/vital-examples/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"@bodiless/vital-table": "^1.0.0-rc.37",
"@bodiless/vital-templates": "^1.0.0-rc.37",
"@bodiless/vital-youtube": "^1.0.0-rc.37",
"@bodiless/vital-section": "^1.0.0-rc.37",
"lodash": "^4.17.19",
"tailwindcss": "^3.0.23"
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React, { FC } from 'react';
import { asVitalTokenSpec } from '@bodiless/vital-elements';
import {
DesignableComponentsProps, Ul, Li, designable, ComponentOrTag, Fragment,
} from '@bodiless/fclasses';

export type ElementsListComponents = {
Wrapper: ComponentOrTag<any>,
ElementWrapper: ComponentOrTag<any>,
ElementToUse: ComponentOrTag<any>,
};

export const elementsListComponents: ElementsListComponents = {
Wrapper: Ul,
ElementWrapper: Li,
ElementToUse: Fragment,
};

const ElementsListBase: FC<DesignableComponentsProps & { times: number }> = props => {
const { times = 4, components } = props;
const { Wrapper, ElementToUse, ElementWrapper } = components;

const items = Array.from(Array(times).keys()).map((val) => (
<ElementWrapper key={val}>
<ElementToUse />
</ElementWrapper>
));

return (
<Wrapper>
{items}
</Wrapper>
);
};

const ElementListClean = designable(elementsListComponents, 'ElementsList')(ElementsListBase);

export const asElementListToken = asVitalTokenSpec<ElementsListComponents>();
export default ElementListClean;
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default as ElementsListClean } from './ElementsListClean';
export { default as elementsList } from './tokens';
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { on } from '@bodiless/fclasses';
import { CardClean, vitalCard } from '@bodiless/vital-card';

import { asElementListToken } from '../ElementsListClean';

const Default = asElementListToken({
Components: {
ElementToUse: on(CardClean)(vitalCard.Default),
},
Layout: {
Wrapper: 'flex',
},
Spacing: {
Wrapper: 'mt-6',
ElementWrapper: 'px-2'
},
});

export default {
Default,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import tokens from './exampleElementsList';

export default tokens;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as exampleSection } from './tokens';
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
import omit from 'lodash/omit';
import { withDefaultContent } from '@bodiless/data';
import { addProps, on } from '@bodiless/fclasses';
import { vitalSection, asSectionToken } from '@bodiless/vital-section';

import { ElementsListClean, elementsList } from '../../ElementsList';

/**
* Hook to provide the default content for the `EditorPlainClean` Title element.
* It returns the object where key is the nodeKey expected for the component (`title` in this case)
* and the value is the data expected by the underlying component.
*/
export const useTitleContent = () => ({
title: { text: 'Hello Section Title!' },
});

/**
* Hook to provide the default content for the `EditorPlainClean` Description element.
* It returns the object where key is the nodeKey expected ('description' in this case)
* and the value is the data expected by the underlying component.
*/
export const useDescriptionContent = () => ({
description: { text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.'}
});

/**
* Default example token for the Section component which adds Section Content.
* Note how we Omit 'Content' and 'Components' domains from the original `vitalSection.Default`.
*
* This is done to illustrate another way to change the original vital token.
* Here we want to make sure we don't inherit the Title and Description from `vitalSection.Default`.
* We will add `WithTitle` and `WithDescription` as standalone tokens.
*/
const Default = asSectionToken(omit(vitalSection.Default, 'Content', 'Components'), {
Spacing: {
Content: 'mt-4'
},
});

/**
* Token that extends the Default and adds the Link to the Section.
* Note that `vitalSection.WithLink` is a token that meant to be layered
* on top of other tokens.
*
* This token *does not* have `With...` in it's name and it indicates that this token is meant
* to be used as a standalone token which can be used *instead* of the `Default` token.
*
* Think of it as a Noun, the token is sufficent by itself to render the component,
* and not just adding a small piece of functionality.
*/
const SectionLink = asSectionToken(Default, {
...vitalSection.WithLink,
Content: {
/**
* Another quick way way to add content such as link text is to add
* children directly to the element like so:
*/
Link: addProps({ children: 'Section Link' }),
}
});

/**
* A token that adds a Link to the Section Component.
*
* Note that the name of this token *starts with* `With...`. That means that the token is meant
* to be layered on top of other tokens and not used by itself. The big difference here is that
* this token *does not extend* the Default token. It is very limited in what this token can do.
*
* Think of it as an Adjective, something that reflects behaviour or additional functionality.
*
* This is the preffered Token pattern since it encourages composition
* and results in a better overall code structure as well as simplifying testing.
*/
const WithSectionLink = asSectionToken({
/**
* The `vitalSection.WithLink` token is also starts with `With...` that indicates that it is
* limited in functionality and meant to enhance the main Token. We take `vitalSection.WithLink`
* and just add default text to the link.
*/
...vitalSection.WithLink,
Content: {
/**
* Another quick way way to add content such as link text is to add
* children directly to the element like so:
*/
Link: addProps({ children: 'Section Link' }),
},
});

/**
* A token that adds a Section Description.
* Description editor setings are inherited from `...vitalSection.WithDescription` Token.
*
* Note that the name of this token *starts with* `With...`. That means that the token is meant
* to be layered on top of other tokens and not used by itself. The big difference here is that
* this token *does not extend* the Default token. It is very limited in what this token can do.
*
* Think of it as an Adjective, something that reflects behaviour or additional functionality.
*
* This is the preffered Token pattern since it encourages composition
* and results in a better overall code structure as well as simplifying testing.
*/
const WithSectionDescription = asSectionToken({
/**
* The `vitalSection.WithDescription` token is also meant to enhance the main Token.
* It provides the Editor for the Section Description and sets `DescriptionWrapper` to `<P>`.
*/
...vitalSection.WithDescription,
Content: {
/**
* We use `withDefaultContent` and the `useDescriptionContent` hook to add the default text
* to the Section Description under the `Content` Domain.
*/
Description: withDefaultContent(useDescriptionContent),
}
});

/**
* A token that adds a Section Title.
* Title editor setings are inherited from `...vitalSection.WithTitle` Token.
*
* Note that the name of this token *starts with* `With...`. That means that the token is meant
* to be layered on top of other tokens and not used by itself. The big difference here is that
* this token *does not extend* the Default token. It is very limited in what this token can do.
*
* Think of it as an Adjective, something that reflects behaviour or additional functionality.
*
* This is the preffered Token pattern since it encourages composition
* and results in a better overall code structure as well as simplifying testing.
*/
const WithSectionTitle = asSectionToken({
/**
* The `vitalSection.WithLink` token is also meant to enhance the main Token.
* It provides the Editor for the Section Title and makes `TitleWrapper` h2.
*/
...vitalSection.WithTitle,
Content: {
/**
* We use `withDefaultContent` and the `useTitleContent` hook to add the default text
* to the Section Title under the `Content` Domain.
*/
Title: withDefaultContent(useTitleContent),
}
});

/**
* A token that adds a list of cards as Content of the Section Component.
*
* Note that the name of this token *starts with* `With...`. That means that the token is meant
* to be layered on top of other tokens and not used by itself. The big difference here is that
* this token *does not extend* the Default token. It is very limited in what this token can do.
*
* Think of it as an Adjective, something that reflects behaviour or additional functionality.
*
* This is the preffered Token pattern since it encourages composition
* and results in a better overall code structure as well as simplifying testing.
*/
const WithSectionCards = asSectionToken({
/**
* Here we will replace the default Section Content with the `ElementsListClean`
* which just repeats it's `ElementToUse` n times. You can specify the number of
* repeats by providing `times` prop.
*/
Components: {
Content: on(ElementsListClean)(elementsList.Default),
},
});

/**
* Export a default `exampleSection` token collection for the Example Section Component.
*/
export default {
Default,
SectionLink,
WithSectionLink,
WithSectionTitle,
WithSectionDescription,
WithSectionCards,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import exampleSection from './exampleSection';

export default exampleSection;
1 change: 1 addition & 0 deletions packages/vital-examples/src/intro/section-example/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './components/Section';
5 changes: 1 addition & 4 deletions packages/vital-section/doc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,7 @@ To add a Vital Section Component to your page:
import { withNodeKey } from '@bodiless/data';
import { SectionClean, vitalSection } from '@bodiless/vital-section';

const DefaultSection = as(
vitalSection.Default,
withNodeKey('defaultbutton'),
)(SectionClean);
const DefaultSection = as(vitalSection.Default)(SectionClean);
```

### Overriding Section
Expand Down
1 change: 1 addition & 0 deletions packages/vital-section/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"@bodiless/components": "^1.0.0-rc.37",
"@bodiless/vital-editors": "^1.0.0-rc.37",
"@bodiless/vital-elements": "^1.0.0-rc.37",
"@bodiless/vital-link": "^1.0.0-rc.37",
"tailwindcss": "^3.0.23"
}
}
19 changes: 15 additions & 4 deletions packages/vital-section/src/Components/Section/SectionClean.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ import { asVitalTokenSpec } from '@bodiless/vital-elements';

import { SectionComponents, SectionBaseProps } from './types';

const sectionComponent: SectionComponents = {
const sectionComponents: SectionComponents = {
Wrapper: Section,
TitleWrapper: Div,
Title: H2,
LinkWrapper: Fragment,
Link: Fragment,
DescriptionWrapper: Fragment,
Description: Fragment,
ContentWrapper: Div,
Content: Div,
ContentWrapper: Fragment,
Content: Fragment,
};

const SectionBase: FC<SectionBaseProps> = ({ components, ...rest }) => {
Expand All @@ -32,6 +32,17 @@ const SectionBase: FC<SectionBaseProps> = ({ components, ...rest }) => {
DescriptionWrapper,
Description,
LinkWrapper,
/**
* Renaming the link because of this error:
*
* `The href attribute is required for an anchor to be keyboard accessible.
* Provide a valid, navigable address as the href value. If you cannot provide an href,
* but still need the element to resemble a link, use a button and change it
* withappropriate styles.
*
* Learn more:
* https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/HEAD/docs/rules/anchor-is-valid.md
*/
Link: SectionLink,
ContentWrapper,
Content,
Expand All @@ -56,7 +67,7 @@ const SectionBase: FC<SectionBaseProps> = ({ components, ...rest }) => {
};

const SectionClean = as(
designable(sectionComponent, 'Section'),
designable(sectionComponents, 'Section'),
withNode,
)(SectionBase);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import vitalSection, { SectionNodeKeys } from './vitalSection';
import vitalSection from './vitalSection';

export default vitalSection;
export { SectionNodeKeys };

0 comments on commit 7c1aa40

Please sign in to comment.