Skip to content

Commit

Permalink
Merge pull request #1339 from gluestack/fix/build-design-system-docs
Browse files Browse the repository at this point in the history
fix: building design system docs
  • Loading branch information
surajahmed authored Oct 27, 2023
2 parents 6951493 + cf74855 commit 18e270a
Show file tree
Hide file tree
Showing 25 changed files with 4,239 additions and 4,112 deletions.
2 changes: 1 addition & 1 deletion _template/package-template/example/native/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"@babel/core": "^7.12.9",
"@expo/webpack-config": "^0.17.2",
"@types/react": "~18.0.14",
"@types/react-native": "~0.70.6",
"@types/react-native": "~0.72.3",
"babel-loader": "8.2.5",
"ts-loader": "~8.2.0",
"typescript": "^4.6.3"
Expand Down
8 changes: 4 additions & 4 deletions _template/package-template/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,20 @@
},
"devDependencies": {
"@types/react": "^18.0.22",
"@types/react-native": "^0.69.15",
"@types/react-native": "^0.72.3",
"babel-plugin-transform-remove-console": "^6.9.4",
"react": "^18.1.0",
"react-dom": "18.1.0",
"react-native": "^0.70.3",
"react-native": "^0.72.4",
"react-native-builder-bob": "^0.20.1",
"react-native-web": "^0.18.1",
"react-native-web": "^0.19.9",
"tsconfig": "*",
"typescript": "^4.7.4"
},
"dependencies": {
"@expo/html-elements": "^0.2.2",
"@gluestack/styled": "*",
"@react-native-aria/focus": "^0.2.7",
"@react-native-aria/focus": "^0.2.9",
"lodash.merge": "^4.6.2"
},
"peerDependencies": {
Expand Down
10 changes: 10 additions & 0 deletions example/apps/expo-app/babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,13 @@ module.exports = function (api) {
],
};
};
function getAliases() {
return {
// For development, we want to alias the library to the source
'@gluestack-ui/themed': path.join(__dirname, '../../packages/themed/src'),
'@gluestack-ui/config': path.join(
__dirname,
'../../packages/config/src/gliesstack-ui.config'
),
};
}
2 changes: 1 addition & 1 deletion example/apps/expo-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"expo": "~49.0.13",
"expo-status-bar": "~1.6.0",
"react": "18.2.0",
"react-native": "0.72.5"
"react-native": "^0.72.4"
},
"devDependencies": {
"@babel/core": "^7.20.0"
Expand Down
4 changes: 4 additions & 0 deletions example/storybook/.storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ module.exports = {
__dirname,
'../../../packages/themed/src'
),
'@gluestack-ui/config': path.join(
__dirname,
'../../../packages/config/src/gluestack-ui.config'
),
};

config.resolve.alias = {
Expand Down
12 changes: 6 additions & 6 deletions example/storybook/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@
"@react-aria/overlays": "^3.13.0",
"@react-aria/separator": "^3.3.0",
"@react-aria/utils": "^3.15.0",
"@react-native-aria/button": "^0.2.4",
"@react-native-aria/overlays": "0.3.7",
"@react-native-aria/separator": "^0.2.5",
"@react-native-aria/button": "^0.2.5",
"@react-native-aria/overlays": "0.3.10",
"@react-native-aria/separator": "^0.2.6",
"@react-native-async-storage/async-storage": "~1.17.3",
"@react-native-community/datetimepicker": "6.5.2",
"@react-native-community/slider": "4.2.4",
Expand All @@ -51,12 +51,12 @@
"re-resizable": "^6.9.11",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-native": "0.72.5",
"react-native": "0.72.4",
"react-native-gesture-handler": "^2.12.1",
"react-native-safe-area-context": "^4.4.1",
"react-native-svg": "13.4.0",
"react-native-vector-icons": "^10.0.0",
"react-native-web": "^0.19.8",
"react-native-web": "^0.19.9",
"react-stately": "^3.21.0",
"shortid": "^2.2.16",
"ts-jest": "^29.1.0",
Expand Down Expand Up @@ -84,7 +84,7 @@
"@storybook/react": "^6.5.14",
"@storybook/react-native": "next",
"@types/react": "^18.0.27",
"@types/react-native": "~0.70.6",
"@types/react-native": "~0.72.3",
"babel-loader": "^8.2.3",
"babel-plugin-react-docgen-typescript": "^1.5.1",
"babel-plugin-react-native-web": "^0.18.10",
Expand Down
4 changes: 1 addition & 3 deletions example/storybook/src/components/Forms/Checkbox/Checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const CheckboxGroupBasic = ({ ...props }: any) => {

return (
<CheckboxGroup
accessibilityLabel="Checkbox Group"
aria-label="Checkbox Group"
value={values}
onChange={setValues}
nativeID="checkbox-group"
Expand All @@ -34,7 +34,6 @@ const CheckboxGroupBasic = ({ ...props }: any) => {
isIndeterminate
value="Label 1"
aria-label="Label 1"
accessibilityLabel="Checkbox"
onChange={(isSelected: boolean) =>
// eslint-disable-next-line no-console
console.log(isSelected, '###')
Expand All @@ -52,7 +51,6 @@ const CheckboxGroupBasic = ({ ...props }: any) => {
size={props.size}
aria-label="Label 2"
value="Label 2"
accessibilityLabel="Checkbox"
onChange={(isSelected: boolean) =>
// eslint-disable-next-line no-console
console.log(isSelected, '###')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -508,10 +508,9 @@ We have outlined the various features that ensure the Checkbox component is acce

#### States

- Setting the `accessibilityState`.
- In error state, `accessibilityInvalid` will be passed to indicate that the radio input has an error, and providing support for an `accessibilityErrorMessage` to describe the error in more detail.
- In disabled state, `accessibilityElementsHidden` will be passed to make radio input not focusable.
- In required state, `accessibilityRequired` will be passed to indicate that the radio input is required.
- In error state, `aria-invalid` will be passed to indicate that the radio input has an error, and providing support for an `aria-errormessage` to describe the error in more detail.
- In disabled state, `aria-hidden` will be passed to make radio input not focusable.
- In required state, `aria-required` will be passed to indicate that the radio input is required.

## Themed

Expand Down
13 changes: 6 additions & 7 deletions example/storybook/src/components/Forms/Input/index.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -385,24 +385,23 @@ We have outlined the various features that ensure the Input component is accessi
#### Keyboard
- Setting the `accessibilityLabel` and `accessibilityHint` to help users understand the purpose and function of the Input
- Setting the `aria-label` and `aria-hint` to help users understand the purpose and function of the Input
#### Screen Reader
- Compatible with screen readers such as VoiceOver and Talk-back.
- The `accessible` and `accessibilityLabel` props to provide descriptive information about the Input
- Setting `accessibilityTraits` and `accessibilityHint` to provide contextual information about the various states of the Input, such as "double tap to edit".
- The `accessible` and `aria-label` props to provide descriptive information about the Input
- Setting `aria-traits` and `aria-hint` to provide contextual information about the various states of the Input, such as "double tap to edit".
#### Focus Management
- The `onFocus` and `onBlur` props to manage focus states and provide visual cues to users. This is especially important for users who rely on keyboard navigation.
#### States
- Setting the `accessibilityState`.
- In error state, `accessibilityInvalid` will be passed to indicate that the Input has an error, and providing support for an `accessibilityErrorMessage` to describe the error in more detail.
- In disabled state, `accessibilityElementsHidden` will be passed to make input not focusable.
- In required state, `accessibilityRequired` will be passed to indicate that the Input is required.
- In error state, `aria-invalid` will be passed to indicate that the Input has an error, and providing support for an `aria-errormessage` to describe the error in more detail.
- In disabled state, `aria-hidden` will be passed to make input not focusable.
- In required state, `aria-required` will be passed to indicate that the Input is required.
## Themed
Expand Down
6 changes: 3 additions & 3 deletions example/storybook/src/components/Forms/Radio/RadioGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const RadioGroupBasic = ({
isInvalid={isInvalid}
size={size}
value="Label 1"
accessibilityLabel="Radio"
aria-label="Label 1"
onChange={(nextValue: boolean) => console.log(nextValue, 'nextValue')}
{...props}
>
Expand All @@ -46,7 +46,7 @@ const RadioGroupBasic = ({
isInvalid={isInvalid}
size={size}
value="Label 2"
accessibilityLabel="Radio"
aria-label="Label 2"
onChange={(nextValue: boolean) => console.log(nextValue, 'nextValue')}
>
<RadioIndicator>
Expand All @@ -61,7 +61,7 @@ const RadioGroupBasic = ({
isInvalid={isInvalid}
size={size}
value="Label 3"
accessibilityLabel="Radio"
aria-label="Label 3"
onChange={(isSelected: boolean) =>
console.log(isSelected, 'isSelected')
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -459,10 +459,9 @@ We have outlined the various features that ensure the Radio component is accessi
#### States
- Setting the `accessibilityState`.
- In error state, `accessibilityInvalid` will be passed to indicate that the radio input has an error, and providing support for an `accessibilityErrorMessage` to describe the error in more detail.
- In disabled state, `accessibilityElementsHidden` will be passed to make radio input not focusable.
- In required state, `accessibilityRequired` will be passed to indicate that the radio input is required.
- In error state, `aria-invalid` will be passed to indicate that the radio input has an error, and providing support for an `aria-errormessage` to describe the error in more detail.
- In disabled state, `aria-hidden` will be passed to make radio input not focusable.
- In required state, `aria-required` will be passed to indicate that the radio input is required.
## Themed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -295,12 +295,12 @@ We have outlined the various features that ensure the Textarea component is acce
#### Keyboard
- setting the accessibilityLabel and accessibilityHint
- setting the aria-label and aria-hint
#### Screen Reader
- VoiceOver: accessible and accessibilityLabel props to describe the input's purpose
- `accessibilityTraits` and `accessibilityHint` for the various states of the input, such as "double tap to edit"
- VoiceOver: accessible and aria-label props to describe the input's purpose
- `aria-traits` and `aria-hint` for the various states of the input, such as "double tap to edit"
## Themed
Expand Down
105 changes: 69 additions & 36 deletions example/storybook/src/guides/building-design-systems/index.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ This enables you to build your own collection of components that match your visi

## Step 1: Create Your Own Package

If you are planning to build your own design system, you can directly **fork** [`@gluestack-ui/themed`](https://github.com/gluestack/gluestack-ui) – a meticulously organized monorepo and begin shaping your design system upon this solid foundation.
If you are planning to build your own design system, you can directly **fork** [`gluestack-ui`](https://github.com/gluestack/gluestack-ui) – a meticulously organized monorepo and begin shaping your design system upon this solid foundation.

- This includes a component library package `@gluestack-ui/themed` in `packages/themed` directory.
- This includes a theme package `@gluestack-ui/config` in `packages/config` directory.
- This includes a storybook for both React and React Native in `example/storybook` directory.

Follow these steps after **forking** this repository:
Expand All @@ -36,6 +37,19 @@ Follow these steps after **forking** this repository:

Now your library `@myapp/components` has all primitive components from `@gluestack-ui/themed` by default.

- Similarly, Navigate to the `packages/config` and open `package.json`. (You can rename the folder if you need).
- Locate the `name` field in `package.json` file and update it to `@myapp/config`.

```json
//package.json
{
"name": "@myapp/config"
// ...
}
```

Now your library `@myapp/config` has all primitive components from `@gluestack-ui/config` by default.

### Update storybook configuration

Navigate to the `example/storybook` and make updates to the specified files below.
Expand All @@ -50,13 +64,14 @@ Navigate to the `example/storybook` and make updates to the specified files belo
// ...
"paths": {
"@myapp/components": ["../../packages/themed/src"],
"@myapp/config": ["../../packages/config/src/gluestack-ui.config"],
},
// ...
}
```

- **_babel.config.js_**:
You'll need to update `alias` in `babel.config.ts` file incase you've renamed the folder `packages/themed`.
You'll need to update `alias` in `babel.config.ts` file incase you've renamed the folder `packages/themed` or `packages/config`.
```jsx
// ... other configuration
plugins: [
Expand All @@ -79,51 +94,69 @@ Navigate to the `example/storybook` and make updates to the specified files belo

### Theme Tokens

Theme tokens and other configuration is present in `packages/themed/src/components/gluestack-ui.config.ts`. You have the flexibility to modify these tokens as per your requirements.
Theme tokens and other configuration is present in `packages/config/src`. You have the flexibility to modify these tokens as per your requirements.

Check [this](/ui/docs/theme-configuration/customizing-theme) for more details.

### Components

You can customize the styling of all primitive components. You can modify styling in `packages/themed/src/components/<ComponentName>/styled-components` for a particular component. You can add and modify property value and variants based on your need.
You can customize the styling of all primitive components. You can modify styling in `packages/config/src/theme/<ComponentName>.ts/` for a particular component. You can add and modify property value and variants based on your need.

**Create a custom component**
To create your own custom component. You need to follow these steps:

- Create a folder inside `packages/themed/src/components/Circle`
- Create a folder `styled-components/` inside `packages/themed/src/components/Circle` to keep all styling.
- Style your component using `@gluestack-style/react` in `Root.tsx`
```jsx
export const Root = styled(View, {
alignItems: 'center',
justifyContent: 'center',
borderRadius: '$full',
overflow: 'hidden',
variants: {
size: {
large: {
width: 100,
height: 100,
},
1. Create a folder inside `packages/themed/src/components/Circle`
2. Create a folder `styled-components/` inside `packages/themed/src/components/Circle` to keep components.
3. Create a styled component using `@gluestack-style/react` in `Root.tsx`, this will be an unstyled component initially with just component name.

```jsx
export const Root = styled(View, {}, { componentName: 'Circle' });
```

5. For other functionalities like accessibility and events, create an `index.tsx` file `packages/themed/src/components/Circle/index.tsx` and export it.

```jsx
import { Root } from './styled-components';

const Circle = (props) => {
return <Root {...props}>{props.children}</Root>;
};
```

6. And then export from `packages/themed/src/components/index.tsx`

```jsx
// other components
export * from './Circle';
```

7. Now we will define theme for `Circle` inside `packages/config/src/theme/Circle.ts`.

```jsx
import { createStyle } from '@gluestack-style/react';

export const Circle = createStyle({
alignItems: 'center',
justifyContent: 'center',
borderRadius: '$full',
overflow: 'hidden',
variants: {
size: {
large: {
width: 100,
height: 100,
},
},
});
```
- For other functionalities like accessibility and events, create an `index.tsx` file `packages/themed/src/components/Circle/index.tsx` and export it.

```jsx
import { Root } from './styled-components';
},
});
```

const Circle = (props) => {
return <Root {...props}>{props.children}</Root>;
};
```
8. And then export from `packages/config/src/index.ts`

- And then export from `packages/themed/src/components/index.tsx`
```jsx
// other components
export * from './Circle';
```
```jsx
// other components
export * from './Circle';
```

## Step 3: Test Your Package

Expand All @@ -136,7 +169,7 @@ export default () => <Circle size="large" />;

## Step 4: Publish Your Package

Now you can publish your design system as a package from `packages/themed`.
Now you can publish your design system as a package from `packages/themed` and theme package from `packages/config`.

## Step 5: Integrate it in Your App

Expand All @@ -152,7 +185,7 @@ const { withGluestackUI } = require('@gluestack/ui-next-adapter');

const nextConfig = {
reactStrictMode: true,
transpilePackages: ['@myapp/components'],
transpilePackages: ['@myapp/components', '@myapp/config'],
};

module.exports = withGluestackUI(nextConfig);
Expand Down
Loading

0 comments on commit 18e270a

Please sign in to comment.