@startupjs-ui/docs 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/README.md +99 -0
- package/client/app/Layout/Sidebar/Content/Docs/index.js +118 -0
- package/client/app/Layout/Sidebar/Content/Docs/index.styl +12 -0
- package/client/app/Layout/Sidebar/Content/Options/index.js +52 -0
- package/client/app/Layout/Sidebar/Content/Options/index.styl +11 -0
- package/client/app/Layout/Sidebar/Content/index.js +38 -0
- package/client/app/Layout/Sidebar/Content/index.styl +35 -0
- package/client/app/Layout/Sidebar/index.js +24 -0
- package/client/app/Layout/index.js +97 -0
- package/client/app/Layout/index.styl +31 -0
- package/client/app/constants.styl +1 -0
- package/client/app/index.js +5 -0
- package/client/app/pages/PDoc/index.js +46 -0
- package/client/app/pages/PDoc/index.styl +21 -0
- package/client/app/pages/PHome/index.js +33 -0
- package/client/app/pages/index.js +2 -0
- package/client/app/routes.js +15 -0
- package/client/clientHelpers/getTitle.js +11 -0
- package/client/clientHelpers/hooks/index.js +6 -0
- package/client/clientHelpers/hooks/useLang.js +12 -0
- package/client/clientHelpers/hooks/useLocalStorage.js +37 -0
- package/client/clientHelpers/hooks/useLocalWithDefault.js +18 -0
- package/client/clientHelpers/hooks/useShowGrid.js +6 -0
- package/client/clientHelpers/hooks/useShowSizes.js +6 -0
- package/client/clientHelpers/hooks/useValidateWidth.js +6 -0
- package/client/clientHelpers/index.js +2 -0
- package/client/components/Props/Constructor/Table/index.js +10 -0
- package/client/components/Props/Constructor/Table/index.styl +2 -0
- package/client/components/Props/Constructor/Tbody/index.js +9 -0
- package/client/components/Props/Constructor/Td/index.js +10 -0
- package/client/components/Props/Constructor/Td/index.styl +4 -0
- package/client/components/Props/Constructor/Thead/index.js +9 -0
- package/client/components/Props/Constructor/Tr/index.js +11 -0
- package/client/components/Props/Constructor/Tr/index.styl +6 -0
- package/client/components/Props/Constructor/TypeCell/index.js +55 -0
- package/client/components/Props/Constructor/ValueCell/index.js +246 -0
- package/client/components/Props/Constructor/index.js +84 -0
- package/client/components/Props/Constructor/index.styl +55 -0
- package/client/components/Props/Renderer/GridVisualizer/index.js +88 -0
- package/client/components/Props/Renderer/GridVisualizer/index.styl +108 -0
- package/client/components/Props/Renderer/index.js +44 -0
- package/client/components/Props/index.js +160 -0
- package/client/components/Props/index.styl +25 -0
- package/client/components/Sandbox/index.js +64 -0
- package/client/components/Sandbox/index.styl +2 -0
- package/client/components/index.js +2 -0
- package/client/const/index.js +2 -0
- package/docsContext.js +17 -0
- package/index.js +13 -0
- package/package.json +29 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Change Log
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
|
+
|
|
6
|
+
## [0.1.3](https://github.com/startupjs/startupjs-ui/compare/v0.1.2...v0.1.3) (2025-12-29)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @startupjs-ui/docs
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## [0.1.2](https://github.com/startupjs/startupjs-ui/compare/v0.1.1...v0.1.2) (2025-12-29)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Features
|
|
18
|
+
|
|
19
|
+
* add mdx and docs packages. Refactor docs to get rid of any @startupjs/ui usage and use startupjs-ui instead ([703c926](https://github.com/startupjs/startupjs-ui/commit/703c92636efb0421ffd11783f692fc892b74018f))
|
package/README.md
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# startupjs docs
|
|
2
|
+
> MDX Documentation generator
|
|
3
|
+
|
|
4
|
+
## TODO:
|
|
5
|
+
|
|
6
|
+
- currently only the Sandbox is usable, still need to update the docs app fully to use the new Expo project and new 'startupjs-ui' components in it.
|
|
7
|
+
|
|
8
|
+
## Prerequisites
|
|
9
|
+
|
|
10
|
+
You must be using `@startupjs/app` for routing.
|
|
11
|
+
|
|
12
|
+
You can create a new application with the routing system using the `routing` template: `npx startupjs init myapp -t routing`
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```sh
|
|
17
|
+
yarn add @startupjs/docs
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Requirements
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
react: 16.9 - 17
|
|
24
|
+
react-native: >= 0.61.4 < 0.64.0
|
|
25
|
+
startupjs: >= 0.33.0
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Usage
|
|
29
|
+
|
|
30
|
+
1. Create the `docs/` folder in your project root.
|
|
31
|
+
|
|
32
|
+
2. Create `docs/index.js` file with the following content:
|
|
33
|
+
```js
|
|
34
|
+
import docs from '@startupjs-ui/docs'
|
|
35
|
+
export default docs({
|
|
36
|
+
typography: {
|
|
37
|
+
type: 'mdx',
|
|
38
|
+
// different titles for mdx documentation in English and Russian
|
|
39
|
+
title: {
|
|
40
|
+
en: 'Typography',
|
|
41
|
+
ru: 'Типографика'
|
|
42
|
+
},
|
|
43
|
+
// different components to display for English and Russian documentation
|
|
44
|
+
component: {
|
|
45
|
+
en: require('../components/typography/Typography.en.mdx').default,
|
|
46
|
+
ru: require('../components/typography/Typography.ru.mdx').default
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
cssGuide: {
|
|
50
|
+
type: 'mdx',
|
|
51
|
+
// the same title for both English and Russian mdx documentation
|
|
52
|
+
title: 'Typography',
|
|
53
|
+
// the same component to display for English and Russian documentation
|
|
54
|
+
component: require('../components/typography/Typography.en.mdx').default
|
|
55
|
+
},
|
|
56
|
+
// docs in collapse
|
|
57
|
+
// items have the same api as mdx docs
|
|
58
|
+
components: {
|
|
59
|
+
type: 'collapse',
|
|
60
|
+
title: {
|
|
61
|
+
en: 'Components',
|
|
62
|
+
ru: 'Компоненты'
|
|
63
|
+
},
|
|
64
|
+
items: {
|
|
65
|
+
Button: {
|
|
66
|
+
type: 'mdx',
|
|
67
|
+
title: {
|
|
68
|
+
en: 'Button',
|
|
69
|
+
ru: 'Кнопка'
|
|
70
|
+
}
|
|
71
|
+
component: {
|
|
72
|
+
en: require('../components/Button/Button.en.mdx').default,
|
|
73
|
+
ru: require('../components/Button/Button.ru.mdx').default
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
Card: {
|
|
77
|
+
type: 'mdx',
|
|
78
|
+
title: 'Card',
|
|
79
|
+
component: require('../components/Card/Card.en.mdx').default
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
})
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
3. Add client-side `docs` app to your `Root/App.js` file:
|
|
87
|
+
|
|
88
|
+
```js
|
|
89
|
+
import docs from '../docs'
|
|
90
|
+
// ...
|
|
91
|
+
<App
|
|
92
|
+
apps={{ main, docs }}
|
|
93
|
+
// ...
|
|
94
|
+
/>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## License
|
|
98
|
+
|
|
99
|
+
MIT
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import React, { useCallback, useEffect, useMemo } from 'react'
|
|
2
|
+
import { pug, observer, useModel, useLocal } from 'startupjs'
|
|
3
|
+
import { pathFor } from 'startupjs/app'
|
|
4
|
+
import { useMedia, Menu, Collapse } from '@startupjs/ui'
|
|
5
|
+
import { faAngleRight } from '@fortawesome/free-solid-svg-icons/faAngleRight'
|
|
6
|
+
import { getTitle, useLang } from '../../../../../clientHelpers'
|
|
7
|
+
import { useDocsContext } from '../../../../../../docsContext'
|
|
8
|
+
import './index.styl'
|
|
9
|
+
|
|
10
|
+
const MenuItem = observer(function MenuItemComponent ({
|
|
11
|
+
active,
|
|
12
|
+
doc,
|
|
13
|
+
docName,
|
|
14
|
+
docPath,
|
|
15
|
+
nestingLevel,
|
|
16
|
+
superPath
|
|
17
|
+
}) {
|
|
18
|
+
const [lang] = useLang()
|
|
19
|
+
const { desktop } = useMedia()
|
|
20
|
+
const $mainSidebar = useModel('_session.Sidebar.mainSidebar')
|
|
21
|
+
const $openedCollapses = useModel('_session.SidebarCollapses')
|
|
22
|
+
|
|
23
|
+
const menuItemStyle = useMemo(() => ({ paddingLeft: nestingLevel * 24 }), [nestingLevel])
|
|
24
|
+
const title = useMemo(() => getTitle(doc, lang), [doc, lang])
|
|
25
|
+
const rootPath = useMemo(() => pathFor('docs:doc', { lang, path: docPath }), [lang, docPath])
|
|
26
|
+
|
|
27
|
+
if (doc.type === 'collapse') {
|
|
28
|
+
return pug`
|
|
29
|
+
Collapse(
|
|
30
|
+
variant='pure'
|
|
31
|
+
$open=$openedCollapses.at(docPath)
|
|
32
|
+
)
|
|
33
|
+
Collapse.Header.header(
|
|
34
|
+
iconPosition='right'
|
|
35
|
+
icon=faAngleRight
|
|
36
|
+
iconStyleName='collapse-icon'
|
|
37
|
+
)
|
|
38
|
+
Menu.Item(
|
|
39
|
+
style=menuItemStyle
|
|
40
|
+
active=active
|
|
41
|
+
to=doc.component ? rootPath : null
|
|
42
|
+
bold
|
|
43
|
+
icon=doc.icon
|
|
44
|
+
)= title
|
|
45
|
+
Collapse.Content
|
|
46
|
+
Docs(
|
|
47
|
+
docs=doc.items
|
|
48
|
+
superPath=docPath
|
|
49
|
+
nestingLevel=nestingLevel + 1
|
|
50
|
+
)
|
|
51
|
+
`
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return pug`
|
|
55
|
+
Menu.Item.item(
|
|
56
|
+
style=menuItemStyle
|
|
57
|
+
active=active
|
|
58
|
+
to=rootPath
|
|
59
|
+
onPress=desktop ? undefined : () => $mainSidebar.set(false)
|
|
60
|
+
)= title
|
|
61
|
+
`
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
const Docs = observer(function DocsComponent ({ docs, superPath, nestingLevel = 1 }) {
|
|
65
|
+
const [path] = useLocal('$render.params.path')
|
|
66
|
+
const $openedCollapses = useModel('_session.SidebarCollapses')
|
|
67
|
+
|
|
68
|
+
// HACK: open parent collapse on initial render
|
|
69
|
+
useEffect(() => {
|
|
70
|
+
if (superPath && path.startsWith(superPath)) {
|
|
71
|
+
$openedCollapses.setDiff(superPath, true)
|
|
72
|
+
}
|
|
73
|
+
}, [])
|
|
74
|
+
|
|
75
|
+
const getDocPath = useCallback(
|
|
76
|
+
docName => {
|
|
77
|
+
return superPath ? superPath + '/' + docName : docName
|
|
78
|
+
},
|
|
79
|
+
[superPath]
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
const getActive = useCallback(
|
|
83
|
+
docName => {
|
|
84
|
+
return getDocPath(docName) === path
|
|
85
|
+
},
|
|
86
|
+
[path]
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
return pug`
|
|
90
|
+
Menu
|
|
91
|
+
each docName in Object.keys(docs)
|
|
92
|
+
MenuItem(
|
|
93
|
+
key=docName
|
|
94
|
+
active=getActive(docName)
|
|
95
|
+
doc=docs[docName]
|
|
96
|
+
docName=docName
|
|
97
|
+
docPath=getDocPath(docName)
|
|
98
|
+
nestingLevel=nestingLevel
|
|
99
|
+
superPath=superPath
|
|
100
|
+
)
|
|
101
|
+
`
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
export default observer(function DocsRoot () {
|
|
105
|
+
const docs = useDocsContext()
|
|
106
|
+
const [path] = useLocal('$render.params.path')
|
|
107
|
+
|
|
108
|
+
// NOTE
|
|
109
|
+
// since layout renders before page loads
|
|
110
|
+
// and $render is created when page loads
|
|
111
|
+
// we need to wait for the 'path' to appear
|
|
112
|
+
// in the params
|
|
113
|
+
if (!path) return null
|
|
114
|
+
|
|
115
|
+
return pug`
|
|
116
|
+
Docs(docs=docs)
|
|
117
|
+
`
|
|
118
|
+
})
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { pug, observer, useValue, $ } from 'startupjs'
|
|
3
|
+
import { Br, Input, Button, Modal } from '@startupjs/ui'
|
|
4
|
+
import { faSlidersH } from '@fortawesome/free-solid-svg-icons/faSlidersH'
|
|
5
|
+
import {
|
|
6
|
+
useShowGrid,
|
|
7
|
+
useShowSizes
|
|
8
|
+
// useValidateWidth
|
|
9
|
+
} from '../../../../../clientHelpers'
|
|
10
|
+
import './index.styl'
|
|
11
|
+
|
|
12
|
+
export default observer(function Options ({
|
|
13
|
+
style
|
|
14
|
+
}) {
|
|
15
|
+
const [, $open] = useValue(false)
|
|
16
|
+
const [, $showGrid] = useShowGrid()
|
|
17
|
+
// TODO: figure out why getting showSizes here leads to a bug of being non-reactive
|
|
18
|
+
// initially. While $showSizes.get() works fine for some reason.
|
|
19
|
+
const [, $showSizes] = useShowSizes()
|
|
20
|
+
// const [, $validateWidth] = useValidateWidth()
|
|
21
|
+
const $theme = $.session.theme
|
|
22
|
+
const theme = $theme.get() || 'light'
|
|
23
|
+
|
|
24
|
+
function toggleTheme () {
|
|
25
|
+
if (theme === 'light') {
|
|
26
|
+
$theme.set('dark')
|
|
27
|
+
} else {
|
|
28
|
+
$theme.set('light')
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return pug`
|
|
33
|
+
Button(
|
|
34
|
+
style=style
|
|
35
|
+
icon=faSlidersH
|
|
36
|
+
color='text-description'
|
|
37
|
+
variant='text'
|
|
38
|
+
onPress=() => $open.set(true)
|
|
39
|
+
)
|
|
40
|
+
Modal(
|
|
41
|
+
title='Settings'
|
|
42
|
+
$visible=$open
|
|
43
|
+
)
|
|
44
|
+
Input.input(type='checkbox' label='Dark theme' value=theme === 'dark' onChange=toggleTheme)
|
|
45
|
+
if $showSizes.get()
|
|
46
|
+
//- TODO: Maybe bring width check back in future
|
|
47
|
+
// Input.input(type='checkbox' label='Validate width' $value=$validateWidth)
|
|
48
|
+
Input.input(type='checkbox' label='Show grid' $value=$showGrid)
|
|
49
|
+
Input.input(type='checkbox' label='Show sizes' $value=$showSizes)
|
|
50
|
+
Br
|
|
51
|
+
`
|
|
52
|
+
})
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { ScrollView, Image } from 'react-native'
|
|
3
|
+
import { pug, observer } from 'startupjs'
|
|
4
|
+
import { Div, Select } from '@startupjs/ui'
|
|
5
|
+
import { BASE_URL } from '@env'
|
|
6
|
+
import { useLang } from '../../../../clientHelpers'
|
|
7
|
+
import Options from './Options'
|
|
8
|
+
import Docs from './Docs'
|
|
9
|
+
import './index.styl'
|
|
10
|
+
|
|
11
|
+
const LANGUAGES = [
|
|
12
|
+
{ value: 'en', label: 'English' },
|
|
13
|
+
{ value: 'ru', label: 'Русский' }
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
export default observer(function Content ({
|
|
17
|
+
style
|
|
18
|
+
}) {
|
|
19
|
+
const [lang, setLang] = useLang()
|
|
20
|
+
// TODO: Change logo image to base64 and pass it through context
|
|
21
|
+
const baseUrl = BASE_URL
|
|
22
|
+
|
|
23
|
+
return pug`
|
|
24
|
+
Div.root
|
|
25
|
+
ScrollView
|
|
26
|
+
Image.logo(testID='logo' source={ uri: baseUrl + '/img/docs.png' })
|
|
27
|
+
Docs
|
|
28
|
+
Div.footer(row)
|
|
29
|
+
Select.lang(
|
|
30
|
+
testID='languagesSelect'
|
|
31
|
+
options=LANGUAGES
|
|
32
|
+
value=lang
|
|
33
|
+
onChange=setLang
|
|
34
|
+
showEmptyValue=false
|
|
35
|
+
)
|
|
36
|
+
Options.options
|
|
37
|
+
`
|
|
38
|
+
})
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
.root
|
|
2
|
+
background-color var(--color-bg-main)
|
|
3
|
+
flex 1
|
|
4
|
+
|
|
5
|
+
.main
|
|
6
|
+
flex 1
|
|
7
|
+
|
|
8
|
+
.subMenuItem
|
|
9
|
+
padding-left 4u
|
|
10
|
+
|
|
11
|
+
.logo
|
|
12
|
+
width 7.5u
|
|
13
|
+
height 7.5u
|
|
14
|
+
align-self center
|
|
15
|
+
margin-top 4u
|
|
16
|
+
margin-bottom 4u
|
|
17
|
+
|
|
18
|
+
.hr
|
|
19
|
+
border-bottom-color var(--color-border-main)
|
|
20
|
+
|
|
21
|
+
.footer
|
|
22
|
+
padding-top 1u
|
|
23
|
+
padding-bottom 1u
|
|
24
|
+
padding-left 2u
|
|
25
|
+
padding-right 0.5u
|
|
26
|
+
background-color var(--color-bg-main-subtle)
|
|
27
|
+
|
|
28
|
+
.lang
|
|
29
|
+
// TODO: flex-grow 1 for some reason gets removed. Research.
|
|
30
|
+
flex-grow 2
|
|
31
|
+
flex-shrink 1
|
|
32
|
+
|
|
33
|
+
.options
|
|
34
|
+
margin-left 0.5u
|
|
35
|
+
flex-shrink 0
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { pug, observer, useModel } from 'startupjs'
|
|
3
|
+
import { SmartSidebar } from '@startupjs/ui'
|
|
4
|
+
import Content from './Content'
|
|
5
|
+
|
|
6
|
+
export const SIDEBAR_PATH = '_session.Sidebar.mainSidebar'
|
|
7
|
+
|
|
8
|
+
function renderContent () {
|
|
9
|
+
return pug`Content`
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export default observer(function Sidebar ({ children }) {
|
|
13
|
+
const $open = useModel(SIDEBAR_PATH)
|
|
14
|
+
|
|
15
|
+
return pug`
|
|
16
|
+
SmartSidebar(
|
|
17
|
+
$open=$open
|
|
18
|
+
width=280
|
|
19
|
+
renderContent=renderContent
|
|
20
|
+
defaultOpen
|
|
21
|
+
)
|
|
22
|
+
= children
|
|
23
|
+
`
|
|
24
|
+
})
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import React, { useState } from 'react'
|
|
2
|
+
import { pug, emit, observer, useModel } from 'startupjs'
|
|
3
|
+
import { pathFor, useLocation } from 'startupjs/app'
|
|
4
|
+
import { AutoSuggest, Button, Div, Layout, Menu, Span } from '@startupjs/ui'
|
|
5
|
+
import { ScrollableProvider } from '@startupjs/scrollable-anchors'
|
|
6
|
+
import { faBars } from '@fortawesome/free-solid-svg-icons/faBars'
|
|
7
|
+
import { faSearch } from '@fortawesome/free-solid-svg-icons/faSearch'
|
|
8
|
+
import Sidebar, { SIDEBAR_PATH } from './Sidebar'
|
|
9
|
+
import { useDocsContext } from '../../../docsContext'
|
|
10
|
+
import { useLang, getTitle } from '../../clientHelpers'
|
|
11
|
+
import './index.styl'
|
|
12
|
+
|
|
13
|
+
function getItems (item, lang, subpath) {
|
|
14
|
+
const docKey = item[0]
|
|
15
|
+
const docPath = subpath ? `${subpath}/${docKey}` : docKey
|
|
16
|
+
const rootPath = pathFor('docs:doc', { lang, path: docPath })
|
|
17
|
+
if (item[1].items) {
|
|
18
|
+
return Object.entries(item[1].items).reduce((acc, item) => {
|
|
19
|
+
return [...acc, ...getItems(item, lang, docPath)]
|
|
20
|
+
}, [])
|
|
21
|
+
} else {
|
|
22
|
+
return [{
|
|
23
|
+
value: rootPath,
|
|
24
|
+
label: getTitle(item[1], lang)
|
|
25
|
+
}]
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function renderItem (item, path) {
|
|
30
|
+
const active = item.value === path
|
|
31
|
+
return pug`
|
|
32
|
+
Menu.Item(
|
|
33
|
+
key=item.value
|
|
34
|
+
)
|
|
35
|
+
Span(
|
|
36
|
+
styleName={active}
|
|
37
|
+
numberOfLines=1
|
|
38
|
+
)= item.label
|
|
39
|
+
`
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const Search = observer(function Search () {
|
|
43
|
+
const [value, setValue] = useState({})
|
|
44
|
+
const { pathname } = useLocation()
|
|
45
|
+
const docs = useDocsContext()
|
|
46
|
+
const [lang] = useLang()
|
|
47
|
+
|
|
48
|
+
const options = Object.entries(docs).reduce((acc, item) => {
|
|
49
|
+
return [...acc, ...getItems(item, lang)]
|
|
50
|
+
}, [])
|
|
51
|
+
|
|
52
|
+
function onChange (value) {
|
|
53
|
+
if (!value) return
|
|
54
|
+
setValue({})
|
|
55
|
+
// TODO: replaced from Menu.Item 'to' property
|
|
56
|
+
emit('url', value.value)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return pug`
|
|
60
|
+
AutoSuggest.search(
|
|
61
|
+
testID='searchInput'
|
|
62
|
+
value=value
|
|
63
|
+
options=options
|
|
64
|
+
placeholder='Search...'
|
|
65
|
+
inputIcon=faSearch
|
|
66
|
+
renderItem=item => renderItem(item, pathname)
|
|
67
|
+
onChange=onChange
|
|
68
|
+
)
|
|
69
|
+
`
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
const Topbar = observer(function Topbar () {
|
|
73
|
+
const $open = useModel(SIDEBAR_PATH)
|
|
74
|
+
|
|
75
|
+
function toggleSidebar () {
|
|
76
|
+
$open.set(!$open.get())
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return pug`
|
|
80
|
+
Div.topbar(row)
|
|
81
|
+
Button(testID='button' variant='text' icon=faBars onPress=toggleSidebar color='text-description')
|
|
82
|
+
Div.searchWrapper
|
|
83
|
+
Search
|
|
84
|
+
`
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
export default observer(function StyleguideLayout ({ children }) {
|
|
88
|
+
// Note: Topbar height is compensated in PDoc
|
|
89
|
+
// to achieve a semi-transparent effect
|
|
90
|
+
return pug`
|
|
91
|
+
Layout.layout(testID="Layout")
|
|
92
|
+
Sidebar
|
|
93
|
+
Topbar
|
|
94
|
+
ScrollableProvider
|
|
95
|
+
= children
|
|
96
|
+
`
|
|
97
|
+
})
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
@require '../constants.styl'
|
|
2
|
+
|
|
3
|
+
.layout
|
|
4
|
+
background-color var(--color-bg-main-strong)
|
|
5
|
+
|
|
6
|
+
.topbar
|
|
7
|
+
align-items center
|
|
8
|
+
justify-content space-between
|
|
9
|
+
border-bottom-width 1px
|
|
10
|
+
border-bottom-color var(--color-border-main-strong-alt)
|
|
11
|
+
height $TOPBAR_HEIGHT
|
|
12
|
+
padding 0 1u
|
|
13
|
+
|
|
14
|
+
.searchWrapper
|
|
15
|
+
width 32u
|
|
16
|
+
border-left-width 1px
|
|
17
|
+
border-left-color var(--color-border-main)
|
|
18
|
+
padding-left 2u
|
|
19
|
+
|
|
20
|
+
+tablet()
|
|
21
|
+
width 42u
|
|
22
|
+
|
|
23
|
+
.search
|
|
24
|
+
max-height 20u
|
|
25
|
+
&:part(input)
|
|
26
|
+
border none
|
|
27
|
+
&:part(icon)
|
|
28
|
+
color var(--color-text-description)
|
|
29
|
+
|
|
30
|
+
.active
|
|
31
|
+
color var(--color-text-primary)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
$TOPBAR_HEIGHT = 6u
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { pug, observer, useLocal } from 'startupjs'
|
|
3
|
+
import { Span, Br, Div } from '@startupjs/ui'
|
|
4
|
+
import { useDocsContext } from '../../../../docsContext'
|
|
5
|
+
import { useLang } from '../../../clientHelpers'
|
|
6
|
+
import './index.styl'
|
|
7
|
+
|
|
8
|
+
export default observer(function PDoc ({
|
|
9
|
+
style
|
|
10
|
+
}) {
|
|
11
|
+
const docs = useDocsContext()
|
|
12
|
+
const [docPath] = useLocal('$render.params.path')
|
|
13
|
+
const segments = docPath.split('/')
|
|
14
|
+
const [lang] = useLang()
|
|
15
|
+
const Component = segments.reduce((docs, segment, index) => {
|
|
16
|
+
const doc = docs[segment]
|
|
17
|
+
if (!doc) return PageNotFound
|
|
18
|
+
// when page with 'collapse' type has a component to render
|
|
19
|
+
// to display it we have to figure out if it is the last segment or not
|
|
20
|
+
if (doc.type === 'collapse' && segments.length - 1 !== index) {
|
|
21
|
+
return doc.items
|
|
22
|
+
}
|
|
23
|
+
const Component = getComponent(doc, lang)
|
|
24
|
+
return Component || PageNotFound
|
|
25
|
+
}, docs)
|
|
26
|
+
|
|
27
|
+
return pug`
|
|
28
|
+
Div.content
|
|
29
|
+
Br
|
|
30
|
+
Component
|
|
31
|
+
Br(lines=4)
|
|
32
|
+
`
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
function PageNotFound () {
|
|
36
|
+
return pug`
|
|
37
|
+
Span.message Page not found
|
|
38
|
+
`
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function getComponent (item, lang) {
|
|
42
|
+
if (!item) return
|
|
43
|
+
if (!item.component) return
|
|
44
|
+
if (item.component[lang]) return item.component[lang]
|
|
45
|
+
return item.component
|
|
46
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
$gutter-l = 6u
|
|
2
|
+
$gutter-xl = 10u
|
|
3
|
+
|
|
4
|
+
.root
|
|
5
|
+
flex 1
|
|
6
|
+
|
|
7
|
+
.content
|
|
8
|
+
padding-left $UI.gutters.m
|
|
9
|
+
padding-right $UI.gutters.m
|
|
10
|
+
max-width $UI.media.tablet + $UI.gutters.m * 2
|
|
11
|
+
+tablet()
|
|
12
|
+
max-width $UI.media.tablet + $gutter-l * 2
|
|
13
|
+
padding-left $gutter-l
|
|
14
|
+
padding-right $gutter-l
|
|
15
|
+
+wide()
|
|
16
|
+
max-width $UI.media.tablet + $gutter-xl * 2
|
|
17
|
+
padding-left $gutter-xl
|
|
18
|
+
padding-right $gutter-xl
|
|
19
|
+
|
|
20
|
+
.message
|
|
21
|
+
font(h2)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { useEffect } from 'react'
|
|
2
|
+
import { observer, emit } from 'startupjs'
|
|
3
|
+
import { useDocsContext } from '../../../../docsContext'
|
|
4
|
+
|
|
5
|
+
export default observer(function PHome () {
|
|
6
|
+
const docs = useDocsContext()
|
|
7
|
+
|
|
8
|
+
function getDocPath (docs) {
|
|
9
|
+
let path = '/'
|
|
10
|
+
const docName = Object.keys(docs)[0]
|
|
11
|
+
const doc = docs[docName]
|
|
12
|
+
switch (doc.type) {
|
|
13
|
+
case 'mdx':
|
|
14
|
+
path += docName
|
|
15
|
+
break
|
|
16
|
+
case 'collapse':
|
|
17
|
+
path += docName
|
|
18
|
+
if (!doc.component) path += getDocPath(doc.items)
|
|
19
|
+
break
|
|
20
|
+
}
|
|
21
|
+
return path
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
emit(
|
|
26
|
+
'url',
|
|
27
|
+
'/docs' + getDocPath(docs),
|
|
28
|
+
{ replace: true }
|
|
29
|
+
)
|
|
30
|
+
}, [])
|
|
31
|
+
|
|
32
|
+
return null
|
|
33
|
+
})
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { DEFAULT_LANGUAGE } from '../const'
|
|
2
|
+
|
|
3
|
+
export default function getTitle (item, lang) {
|
|
4
|
+
const title = item.title
|
|
5
|
+
? typeof item.title === 'string'
|
|
6
|
+
? item.title
|
|
7
|
+
: item.title[lang] || item.title[DEFAULT_LANGUAGE]
|
|
8
|
+
: null
|
|
9
|
+
if (!title) throw Error('No title specified')
|
|
10
|
+
return title
|
|
11
|
+
}
|