@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.
Files changed (51) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +99 -0
  3. package/client/app/Layout/Sidebar/Content/Docs/index.js +118 -0
  4. package/client/app/Layout/Sidebar/Content/Docs/index.styl +12 -0
  5. package/client/app/Layout/Sidebar/Content/Options/index.js +52 -0
  6. package/client/app/Layout/Sidebar/Content/Options/index.styl +11 -0
  7. package/client/app/Layout/Sidebar/Content/index.js +38 -0
  8. package/client/app/Layout/Sidebar/Content/index.styl +35 -0
  9. package/client/app/Layout/Sidebar/index.js +24 -0
  10. package/client/app/Layout/index.js +97 -0
  11. package/client/app/Layout/index.styl +31 -0
  12. package/client/app/constants.styl +1 -0
  13. package/client/app/index.js +5 -0
  14. package/client/app/pages/PDoc/index.js +46 -0
  15. package/client/app/pages/PDoc/index.styl +21 -0
  16. package/client/app/pages/PHome/index.js +33 -0
  17. package/client/app/pages/index.js +2 -0
  18. package/client/app/routes.js +15 -0
  19. package/client/clientHelpers/getTitle.js +11 -0
  20. package/client/clientHelpers/hooks/index.js +6 -0
  21. package/client/clientHelpers/hooks/useLang.js +12 -0
  22. package/client/clientHelpers/hooks/useLocalStorage.js +37 -0
  23. package/client/clientHelpers/hooks/useLocalWithDefault.js +18 -0
  24. package/client/clientHelpers/hooks/useShowGrid.js +6 -0
  25. package/client/clientHelpers/hooks/useShowSizes.js +6 -0
  26. package/client/clientHelpers/hooks/useValidateWidth.js +6 -0
  27. package/client/clientHelpers/index.js +2 -0
  28. package/client/components/Props/Constructor/Table/index.js +10 -0
  29. package/client/components/Props/Constructor/Table/index.styl +2 -0
  30. package/client/components/Props/Constructor/Tbody/index.js +9 -0
  31. package/client/components/Props/Constructor/Td/index.js +10 -0
  32. package/client/components/Props/Constructor/Td/index.styl +4 -0
  33. package/client/components/Props/Constructor/Thead/index.js +9 -0
  34. package/client/components/Props/Constructor/Tr/index.js +11 -0
  35. package/client/components/Props/Constructor/Tr/index.styl +6 -0
  36. package/client/components/Props/Constructor/TypeCell/index.js +55 -0
  37. package/client/components/Props/Constructor/ValueCell/index.js +246 -0
  38. package/client/components/Props/Constructor/index.js +84 -0
  39. package/client/components/Props/Constructor/index.styl +55 -0
  40. package/client/components/Props/Renderer/GridVisualizer/index.js +88 -0
  41. package/client/components/Props/Renderer/GridVisualizer/index.styl +108 -0
  42. package/client/components/Props/Renderer/index.js +44 -0
  43. package/client/components/Props/index.js +160 -0
  44. package/client/components/Props/index.styl +25 -0
  45. package/client/components/Sandbox/index.js +64 -0
  46. package/client/components/Sandbox/index.styl +2 -0
  47. package/client/components/index.js +2 -0
  48. package/client/const/index.js +2 -0
  49. package/docsContext.js +17 -0
  50. package/index.js +13 -0
  51. package/package.json +29 -0
@@ -0,0 +1,88 @@
1
+ import React from 'react'
2
+ import { pug, observer, $ } from 'startupjs'
3
+ import { themed } from '@startupjs-ui/core'
4
+ import Div from '@startupjs-ui/div'
5
+ import Span from '@startupjs-ui/span'
6
+ import './index.styl'
7
+
8
+ const GRID_SIZE = 8
9
+ const VALIDATE_WIDTH = false
10
+ const VALIDATE_HEIGHT = true
11
+ const ALLOW_HALF_UNIT = true
12
+
13
+ export default observer(function GridVisualizer ({
14
+ validateWidth = VALIDATE_WIDTH,
15
+ validateHeight = VALIDATE_HEIGHT,
16
+ allowHalfUnit = ALLOW_HALF_UNIT,
17
+ showGrid,
18
+ block,
19
+ style,
20
+ children
21
+ }) {
22
+ const $componentSize = $.session.Renderer.componentSize
23
+
24
+ function onLayout (e) {
25
+ const { width, height } = e.nativeEvent.layout
26
+ $componentSize.set({ width, height })
27
+ }
28
+
29
+ // TODO: Bring back width check as an option. For now it's commented out.
30
+ return pug`
31
+ Div.vertical(row)
32
+ LeftBar(
33
+ allowHalfUnit=allowHalfUnit
34
+ validate=validateHeight
35
+ )
36
+ // TopBar(allowHalfUnit=allowHalfUnit validate=validateWidth)
37
+ // it's style for component wrapper!!!
38
+ Div.content(
39
+ style=style
40
+ styleName={ block }
41
+ onLayout=onLayout
42
+ )
43
+ | #{children}
44
+ if showGrid
45
+ Div.gridVisualizer(pointerEvents='none')
46
+ `
47
+ })
48
+
49
+ const LeftBar = observer(themed(({ allowHalfUnit, validate, theme }) => {
50
+ const $height = $.session.Renderer.componentSize.height
51
+ const height = $height.get() || 0
52
+ const units = toUnits(height)
53
+ const valid = validate ? validateGrid(height, allowHalfUnit) : true
54
+
55
+ return pug`
56
+ Div.leftBar
57
+ Div.leftBarWrapper(style={ width: height } row)
58
+ Div.leftBarLine(styleName=[theme, { valid }])
59
+ Span.leftBarText(styleName=[theme, { valid }])= units
60
+ Div.leftBarLine(styleName=[theme, { valid }])
61
+ `
62
+ }))
63
+
64
+ // TODO: Bring back width check as an option. For now it's commented out.
65
+ // const TopBar = observer(themed(({ allowHalfUnit, validate, theme }) => {
66
+ // let [width = 0] = useLocal('_session.Renderer.componentSize.width')
67
+ // let units = toUnits(width)
68
+ // let valid = validate ? validateGrid(width, allowHalfUnit) : true
69
+
70
+ // return pug`
71
+ // View.topBar
72
+ // View.topBarLine(styleName=[theme, { valid }])
73
+ // View.topBarUnits
74
+ // Text.topBarText(styleName=[theme, { valid }])= NBSP + units + NBSP
75
+ // View.topBarLine(styleName=[theme, { valid }])
76
+ // `
77
+ // }))
78
+
79
+ function toUnits (pixels) {
80
+ return Math.floor(pixels / GRID_SIZE * 10) / 10
81
+ }
82
+
83
+ function validateGrid (pixels, allowHalfUnit) {
84
+ return (
85
+ pixels % GRID_SIZE === 0 ||
86
+ (allowHalfUnit && pixels % (GRID_SIZE / 2) === 0)
87
+ )
88
+ }
@@ -0,0 +1,108 @@
1
+ $major = rgba(green, 0.15)
2
+ $minor = rgba(black, 0.05)
3
+ $size = 1u
4
+ $double = $size * 2
5
+ $bar = 2u
6
+ $barMargin = 1u
7
+ $valid = rgba(black, 0.2)
8
+ $validLine = rgba(black, 0.1)
9
+ $invalid = red
10
+ $bg = #f5f5f5
11
+
12
+ $darkBg = #333333
13
+ $darkValid = rgba(white, 0.3)
14
+ $darkInvalid = lighten(red, 40%)
15
+ $darkValidLine = rgba(white, 0.2)
16
+
17
+ grid(direction, color, size)
18
+ return linear-gradient(direction, color 0px, color 1px, transparent 1px, transparent size)
19
+
20
+ .gridVisualizer
21
+ position absolute
22
+ top 0
23
+ right 0
24
+ bottom 0
25
+ left 0
26
+ +web()
27
+ pointer-events none
28
+ background-image grid(to right, $major, $double), grid(to bottom, $major, $double), grid(to right, $minor, $double), grid(to bottom, $minor, $double)
29
+ background-size $double $double, $double $double, $double $double, $double $double
30
+ background-position 0 0, 0 0, $size $size, $size $size
31
+ background-repeat repeat, repeat, repeat, repeat
32
+
33
+ .filler
34
+ height $bar + $barMargin
35
+ width $bar
36
+
37
+ .content
38
+ margin-left 2u
39
+
40
+ &.block
41
+ flex-grow 1
42
+
43
+ .leftBar
44
+ align-items center
45
+ justify-content center
46
+
47
+ &Wrapper
48
+ align-items center
49
+ transform rotate(-90deg)
50
+ position absolute
51
+
52
+ &Text
53
+ font-size 10px
54
+ color $invalid
55
+ margin 0 .5u
56
+
57
+ &.valid
58
+ color $valid
59
+ &.dark
60
+ background-color $darkBg
61
+ color $darkInvalid
62
+ &.valid
63
+ color $darkValid
64
+
65
+ &Line
66
+ flex 1
67
+ height 0.5u
68
+ background-color $invalid
69
+ &.valid
70
+ height 1px
71
+ background-color $validLine
72
+ &.dark
73
+ background-color $darkInvalid
74
+ &.valid
75
+ background-color $darkValidLine
76
+
77
+ .topBar
78
+ flex-direction row
79
+ height $bar
80
+ margin-bottom $barMargin
81
+ align-items center
82
+
83
+ &Units
84
+ z-index 1
85
+
86
+ &Text
87
+ font-size 10px
88
+ color $invalid
89
+ background-color $bg
90
+ &.valid
91
+ color $valid
92
+ &.dark
93
+ background-color $darkBg
94
+ color $darkInvalid
95
+ &.valid
96
+ color $darkValid
97
+
98
+ &Line
99
+ flex 1
100
+ height 0.5u
101
+ background-color $invalid
102
+ &.valid
103
+ height 1px
104
+ background-color $validLine
105
+ &.dark
106
+ background-color $darkInvalid
107
+ &.valid
108
+ background-color $darkValidLine
@@ -0,0 +1,44 @@
1
+ import React from 'react'
2
+ import { pug, observer } from 'startupjs'
3
+ import { themed } from '@startupjs-ui/core'
4
+ import Div from '@startupjs-ui/div'
5
+ import GridVisualizer from './GridVisualizer'
6
+
7
+ export default observer(themed(function Renderer ({
8
+ Component,
9
+ props: {
10
+ children,
11
+ ...props
12
+ },
13
+ showSizes = true,
14
+ showGrid,
15
+ validateWidth,
16
+ validateHeight,
17
+ allowHalfUnit,
18
+ theme,
19
+ block,
20
+ style
21
+ }) {
22
+ let Wrapper
23
+ const extraProps = {}
24
+ if (showSizes) {
25
+ Wrapper = GridVisualizer
26
+ extraProps.block = block
27
+ } else {
28
+ Wrapper = Div
29
+ extraProps.row = !block
30
+ }
31
+
32
+ return pug`
33
+ Wrapper(
34
+ ...extraProps
35
+ style=style
36
+ validateWidth=validateWidth
37
+ validateHeight=validateHeight
38
+ allowHalfUnit=allowHalfUnit
39
+ showGrid=showGrid
40
+ )
41
+ Component(...props)
42
+ = children
43
+ `
44
+ }))
@@ -0,0 +1,160 @@
1
+ import React, { useMemo, useState } from 'react'
2
+ import { pug, observer, $, useId } from 'startupjs'
3
+ import { themed } from '@startupjs-ui/core'
4
+ import Button from '@startupjs-ui/button'
5
+ import Div from '@startupjs-ui/div'
6
+ import ScrollView from '@startupjs-ui/scroll-view'
7
+ import Constructor from './Constructor'
8
+ import Renderer from './Renderer'
9
+ import './index.styl'
10
+
11
+ function useEntries ({ Component, props, extraParams, propsJsonSchema }) {
12
+ return useMemo(() => {
13
+ if (!propsJsonSchema?.properties) return []
14
+ const entries = Object.entries(propsJsonSchema.properties)
15
+
16
+ const res = parseEntries(entries)
17
+ .filter(entry => entry.name[0] !== '_') // skip private properties
18
+
19
+ for (const key in props) {
20
+ const item = res.find(item => item.name === key)
21
+ if (item) {
22
+ item.value = props[key]
23
+ } else {
24
+ res.push({
25
+ name: key,
26
+ type: typeof props[key],
27
+ value: props[key]
28
+ })
29
+ }
30
+ }
31
+
32
+ for (const key in extraParams) {
33
+ const item = res.find(item => item.name === key)
34
+ if (item) item.extraParams = extraParams[key]
35
+ }
36
+
37
+ return res
38
+ }, [extraParams, props, propsJsonSchema])
39
+ }
40
+
41
+ function parseEntries (entries) {
42
+ return entries.map(entry => {
43
+ const name = entry[0]
44
+ const meta = entry[1]
45
+ let type = meta.type
46
+ if (meta.enum) type = 'oneOf'
47
+ if (meta.$comment && meta.$comment.startsWith('(')) type = 'function'
48
+ if (!type) type = 'any'
49
+ let extendedFrom = meta.extendedFrom
50
+ // children prop is special, it should not be marked as extendedFrom
51
+ if (name === 'children') extendedFrom = undefined
52
+ return {
53
+ name,
54
+ type,
55
+ defaultValue: meta.default,
56
+ possibleValues: meta.enum,
57
+ isRequired: meta.required,
58
+ description: meta.description,
59
+ extendedFrom
60
+ }
61
+ })
62
+ }
63
+
64
+ function useInitDefaultProps ({ entries, $theProps }) {
65
+ if ($theProps.get()) return
66
+ $theProps.set({})
67
+
68
+ for (const { name, value, defaultValue } of entries) {
69
+ // When accessing property which starts with '$' it gets removed by Signal's Proxy
70
+ // that's why we need to add an extra '$' at the beginning to access the original name
71
+ const $prop = name.startsWith('$') ? $theProps['$' + name] : $theProps[name]
72
+ if (value !== undefined) {
73
+ $prop.set(value)
74
+ } else if (defaultValue !== undefined) {
75
+ $prop.set(defaultValue)
76
+ }
77
+ }
78
+ }
79
+
80
+ export default observer(themed(function PComponent ({
81
+ style,
82
+ rendererStyle,
83
+ Component,
84
+ $props,
85
+ props,
86
+ propsJsonSchema,
87
+ extraParams,
88
+ componentName,
89
+ showGrid,
90
+ validateWidth,
91
+ showSizes,
92
+ noScroll,
93
+ block: defaultBlock
94
+ }) {
95
+ const [block, setBlock] = useState(!!defaultBlock)
96
+ const componentId = useId()
97
+
98
+ const $theProps = useMemo(() => {
99
+ if (!$props) {
100
+ return $.session.Props[componentId]
101
+ } else {
102
+ return $props
103
+ }
104
+ }, [$props, componentId])
105
+
106
+ const entries = useEntries({ Component, props, extraParams, propsJsonSchema })
107
+ useInitDefaultProps({ entries, $theProps })
108
+
109
+ function Wrapper ({ children }) {
110
+ if (noScroll) {
111
+ return pug`
112
+ Div.scroll.scrollContent
113
+ = children
114
+ `
115
+ }
116
+
117
+ return pug`
118
+ ScrollView.scroll(
119
+ contentContainerStyleName='scrollContent'
120
+ horizontal
121
+ )= children
122
+ `
123
+ }
124
+
125
+ return pug`
126
+ Div.root(style=style)
127
+ Div.top
128
+ Constructor(
129
+ Component=Component
130
+ extendedFrom=propsJsonSchema?.extendedFrom
131
+ $props=$theProps
132
+ entries=entries
133
+ )
134
+
135
+ Div.bottom
136
+ Wrapper
137
+ Renderer(
138
+ style=rendererStyle
139
+ Component=Component
140
+ props=$theProps.get()
141
+ showGrid=showGrid
142
+ validateWidth=validateWidth
143
+ showSizes=showSizes
144
+ block=block
145
+ )
146
+ Div.display(align='right' row)
147
+ Button(
148
+ size='s'
149
+ variant='text'
150
+ color=block ? undefined : 'primary'
151
+ onPress=() => setBlock(false)
152
+ ) inline
153
+ Button(
154
+ size='s'
155
+ variant='text'
156
+ color=block ? 'primary' : undefined
157
+ onPress=() => setBlock(true)
158
+ ) block
159
+ `
160
+ }))
@@ -0,0 +1,25 @@
1
+ .root
2
+ margin-top 2u
3
+
4
+ .top
5
+ background-color var(--color-bg-main)
6
+ border-top-left-radius 1u
7
+ border-top-right-radius 1u
8
+ padding-top 1u
9
+
10
+ .bottom
11
+ padding-top 4u
12
+ background-color var(--color-bg-main-subtle)
13
+ border-bottom-left-radius 1u
14
+ border-bottom-right-radius 1u
15
+
16
+ .scroll
17
+ padding-bottom 2u
18
+
19
+ &Content
20
+ flex-direction column
21
+ flex-grow 1
22
+ padding 0 2u
23
+
24
+ .display
25
+ margin .5u 2u
@@ -0,0 +1,64 @@
1
+ import React from 'react'
2
+ import { pug, observer, $, useId } from 'startupjs'
3
+ import Span from '@startupjs-ui/span'
4
+ import Alert from '@startupjs-ui/alert'
5
+ import Props from '../Props'
6
+ import {
7
+ useShowGrid,
8
+ useShowSizes,
9
+ useValidateWidth
10
+ } from '../../clientHelpers'
11
+ import './index.styl'
12
+
13
+ const MODELS = new WeakMap()
14
+
15
+ export default observer(function Sandbox ({
16
+ Component,
17
+ propsJsonSchema,
18
+ $props,
19
+ ...otherProps
20
+ }) {
21
+ const [showGrid] = useShowGrid()
22
+ const [showSizes] = useShowSizes()
23
+ const [validateWidth] = useValidateWidth()
24
+ const uniqId = useId()
25
+
26
+ if (!Component) {
27
+ return pug`
28
+ Span.error(h4) ERROR! Sandbox Component not specified
29
+ `
30
+ }
31
+
32
+ if (typeof propsJsonSchema !== 'object' || Object.keys(propsJsonSchema).length === 0) {
33
+ return pug`
34
+ Alert(variant='error')
35
+ | No propsJsonSchema provided for the Sandbox component (or it's an empty object).
36
+ | Make sure that:
37
+ | 1. your component file has the magic 'const export _PropsJsonSchema = ' declaration;
38
+ | 2. your component file has 'export interface' with props interface declared;
39
+ | 3. you import the '_PropsJsonSchema' from the component file
40
+ | and pass it to the Sandbox as 'propsJsonSchema' prop;
41
+ | 4. 'babel-preset-startupjs' must have an option 'docgen: true' enabled
42
+ | to transform the TS interface to JSON schema at build time.
43
+ `
44
+ }
45
+
46
+ return pug`
47
+ Props.root(
48
+ Component=Component
49
+ propsJsonSchema=propsJsonSchema
50
+ $props=$props || getUniqModel(Component, uniqId)
51
+ showSizes=showSizes
52
+ showGrid=showGrid
53
+ validateWidth=validateWidth
54
+ ...otherProps
55
+ )
56
+ `
57
+ })
58
+
59
+ function getUniqModel (Component, uniqId) {
60
+ if (MODELS.has(Component)) return MODELS.get(Component)
61
+ const $uniqModel = $.session.Props[uniqId]
62
+ MODELS.set(Component, $uniqModel)
63
+ return $uniqModel
64
+ }
@@ -0,0 +1,2 @@
1
+ .error
2
+ color var(--color-text-error)
@@ -0,0 +1,2 @@
1
+ export { default as Props } from './Props'
2
+ export { default as Sandbox } from './Sandbox'
@@ -0,0 +1,2 @@
1
+ export const DEFAULT_LANGUAGE = 'en'
2
+ export const LANGUAGES = ['en', 'ru']
package/docsContext.js ADDED
@@ -0,0 +1,17 @@
1
+ import { useContext, createContext } from 'react'
2
+
3
+ const DocsContext = createContext()
4
+
5
+ export function wrapDocsContext (Component, docs = {}) {
6
+ return function DocsContextWrapper (props) {
7
+ return (
8
+ <DocsContext.Provider value={docs}>
9
+ <Component {...props} />
10
+ </DocsContext.Provider>
11
+ )
12
+ }
13
+ }
14
+
15
+ export function useDocsContext () {
16
+ return useContext(DocsContext)
17
+ }
package/index.js ADDED
@@ -0,0 +1,13 @@
1
+ // TODO: refactor docs app to work with the new expo app structure
2
+ // import { routes, Layout } from './client/app'
3
+ // import { wrapDocsContext } from './docsContext'
4
+
5
+ // // Wrap Layout into context.
6
+ // export default function (docs) {
7
+ // return {
8
+ // routes,
9
+ // Layout: wrapDocsContext(Layout, docs)
10
+ // }
11
+ // }
12
+
13
+ export * from './client/components'
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@startupjs-ui/docs",
3
+ "description": "MDX documentation generator",
4
+ "version": "0.1.3",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "type": "module",
9
+ "main": "index.js",
10
+ "dependencies": {
11
+ "@fortawesome/free-solid-svg-icons": "^5.12.0",
12
+ "@startupjs-ui/alert": "^0.1.3",
13
+ "@startupjs-ui/br": "^0.1.3",
14
+ "@startupjs-ui/button": "^0.1.3",
15
+ "@startupjs-ui/core": "^0.1.3",
16
+ "@startupjs-ui/div": "^0.1.3",
17
+ "@startupjs-ui/input": "^0.1.3",
18
+ "@startupjs-ui/scroll-view": "^0.1.3",
19
+ "@startupjs-ui/span": "^0.1.3",
20
+ "@startupjs-ui/tag": "^0.1.3",
21
+ "lodash": "^4.17.20"
22
+ },
23
+ "peerDependencies": {
24
+ "react": "*",
25
+ "react-native": "*",
26
+ "startupjs": "*"
27
+ },
28
+ "gitHead": "fd964ebc3892d3dd0a6c85438c0af619cc50c3f0"
29
+ }