@startupjs-ui/core 0.1.1 → 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.
@@ -0,0 +1,13 @@
1
+ import Color from 'color'
2
+
3
+ const DEFAULT_OPACITY = 1
4
+
5
+ export default function colorToRGBA (color, alpha) {
6
+ try {
7
+ const fadeRatio = (DEFAULT_OPACITY * 100 - alpha * 100) / 100
8
+ return Color(color).fade(fadeRatio).toString()
9
+ } catch (err) {
10
+ console.error('ERROR:', err.message)
11
+ return color
12
+ }
13
+ }
@@ -0,0 +1,3 @@
1
+ export { default as u } from './u'
2
+ export { default as colorToRGBA } from './colorToRGBA'
3
+ export { $ui } from './path'
@@ -0,0 +1,3 @@
1
+ import { $ } from 'startupjs'
2
+
3
+ export const $ui = $.session.ui
package/helpers/u.js ADDED
@@ -0,0 +1,3 @@
1
+ export default function u (value = 0) {
2
+ return value * 8
3
+ }
package/hooks/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { default as useMedia } from './useMedia'
2
+ export { default as useCssVariables } from './useCssVariables'
3
+ export { default as useTransformCssVariables } from './useTransformCssVariables'
4
+ export { default as useColors } from './useColors'
@@ -0,0 +1,16 @@
1
+ import { useCallback } from 'react'
2
+ import { variables as singletonVariables, defaultVariables } from 'startupjs'
3
+
4
+ export default function useColors () {
5
+ return useCallback(getColor, [])
6
+ }
7
+
8
+ export function getColor (color, { prefix = '--color', convertToString = true } = {}) {
9
+ if (!color) return
10
+
11
+ const cssVar = `${prefix}-${color}`
12
+ const colorInstance = singletonVariables[cssVar] || defaultVariables[cssVar]
13
+ if (!colorInstance) return
14
+
15
+ return convertToString ? colorInstance.toString() : colorInstance
16
+ }
@@ -0,0 +1,5 @@
1
+ import { variables as singletonVariables } from 'startupjs'
2
+
3
+ export default function useCssVariables () {
4
+ return singletonVariables
5
+ }
@@ -0,0 +1,28 @@
1
+ import useMedia from '../hooks/useMedia'
2
+ import Button from './../components/Button/'
3
+ import { faHome } from '@fortawesome/free-solid-svg-icons'
4
+
5
+ # useMedia
6
+
7
+ Allows you to determine a device resolution. Hook returns an object where key is media breakpoint (`wide`, `desktop`, `tablet`) and value is `true/false`. For example, using this hook you can create media queries.
8
+
9
+ ```jsx
10
+ import { useMedia } from 'startupjs/ui'
11
+ ```
12
+
13
+ ## Media query example
14
+
15
+ For the test, you need to change the width of the screen, the inscription "Home" from the button should disappear
16
+
17
+ ```jsx example
18
+ const media = useMedia()
19
+ const props = {}
20
+ if (media.tablet) props.children = 'Home'
21
+ return (
22
+ <Button
23
+ icon={faHome}
24
+ onPress={()=> alert('For testing, follow the described instructions')}
25
+ {...props}
26
+ />
27
+ )
28
+ ```
@@ -0,0 +1,37 @@
1
+ import { Dimensions } from 'react-native'
2
+ import { observable } from '@nx-js/observer-util'
3
+ import debounce from 'lodash/debounce'
4
+ import STYLES from './useMedia.styl'
5
+
6
+ const { media } = STYLES
7
+
8
+ const { mobile, ...MEDIA } = media // mobile is DEPRECATED
9
+ const DIMENSIONS_UPDATE_DELAY = 200
10
+ const mediaFlags = observable({})
11
+
12
+ const debouncedUpdateMedia = debounce(
13
+ updateMediaFlags,
14
+ DIMENSIONS_UPDATE_DELAY,
15
+ { leading: false, trailing: true }
16
+ )
17
+
18
+ listenForMediaUpdates()
19
+
20
+ export default function useMedia () {
21
+ return mediaFlags
22
+ }
23
+
24
+ function updateMediaFlags ({ window }) {
25
+ for (const breakpoint of Object.keys(MEDIA).reverse()) {
26
+ if (window.width >= MEDIA[breakpoint]) {
27
+ if (!mediaFlags[breakpoint]) mediaFlags[breakpoint] = true
28
+ } else {
29
+ if (mediaFlags[breakpoint]) mediaFlags[breakpoint] = false
30
+ }
31
+ }
32
+ }
33
+
34
+ function listenForMediaUpdates () {
35
+ updateMediaFlags({ window: Dimensions.get('window') })
36
+ Dimensions.addEventListener('change', debouncedUpdateMedia)
37
+ }
@@ -0,0 +1,28 @@
1
+ import useMedia from '../hooks/useMedia'
2
+ import Button from './../components/Button/'
3
+ import { faHome } from '@fortawesome/free-solid-svg-icons'
4
+
5
+ # useMedia
6
+
7
+ Позволяет определить разрешение устройства. Хук возвращает объект, где ключ - это медиа-точка останова (`wide`, `desktop`, `tablet`), а значение - `true/false`. Например, с помощью этого хука вы можете создавать медиа-запросы.
8
+
9
+ ```jsx
10
+ import { useMedia } from 'startupjs/ui'
11
+ ```
12
+
13
+ ## Пример медиа-запроса
14
+
15
+ Для теста нужно изменить ширину экрана, должна пропасть надпись "Home" из кнопки
16
+
17
+ ```jsx example
18
+ const media = useMedia()
19
+ const props = {}
20
+ if (media.tablet) props.children = 'Home'
21
+ return (
22
+ <Button
23
+ icon={faHome}
24
+ onPress={()=> alert('Для тестирования следуйте описанным инструкциям.')}
25
+ {...props}
26
+ />
27
+ )
28
+ ```
@@ -0,0 +1,2 @@
1
+ :export
2
+ media: $UI.media
@@ -0,0 +1,37 @@
1
+ import { useCallback } from 'react'
2
+ import { variables as singletonVariables } from 'startupjs'
3
+
4
+ const VARS_REGEX = /"var\(\s*(--[A-Za-z0-9_-]+)\s*,?\s*(.*?)\s*\)"/g
5
+
6
+ export default function useTransformCssVariables (styles) {
7
+ return useCallback(transformCssVariable, [])
8
+ }
9
+
10
+ function transformCssVariable (styles) {
11
+ let strStyles = JSON.stringify(styles)
12
+ strStyles = strStyles.replace(VARS_REGEX, (match, varName, varDefault) => {
13
+ let res
14
+ if (singletonVariables[varName] != null) {
15
+ res = singletonVariables[varName]
16
+ } else {
17
+ res = varDefault
18
+ }
19
+ if (typeof res === 'string') {
20
+ res = res.trim()
21
+ // replace 'px' value with a pure number
22
+ res = res.replace(/px$/, '')
23
+ // sometimes compiler returns wrapped brackets. Remove them
24
+ const bracketsCount = res.match(/^\(+/)?.[0]?.length || 0
25
+ res = res.substring(bracketsCount, res.length - bracketsCount)
26
+ }
27
+ if (!isNumeric(res)) {
28
+ res = `"${res}"`
29
+ }
30
+ return res
31
+ })
32
+ return JSON.parse(strStyles)
33
+ }
34
+
35
+ function isNumeric (num) {
36
+ return (typeof num === 'number' || (typeof num === 'string' && num.trim() !== '')) && !isNaN(num)
37
+ }
package/index.d.ts ADDED
@@ -0,0 +1,79 @@
1
+ import type * as React from 'react'
2
+
3
+ export function u (value?: number): number
4
+
5
+ export function colorToRGBA (color: string, alpha?: number): string
6
+
7
+ export interface GetCssVariableOptions {
8
+ convertToString?: boolean
9
+ }
10
+
11
+ export type CssVariableValue = string | undefined | Record<string, any>
12
+
13
+ export function getCssVariable (
14
+ cssVarName: string,
15
+ options?: GetCssVariableOptions
16
+ ): CssVariableValue
17
+
18
+ export interface CssVariablesMeta {
19
+ palette?: Record<string, any>
20
+ colors?: Record<string, any>
21
+ componentColors?: Record<string, any>
22
+ }
23
+
24
+ export interface CssVariablesProps {
25
+ meta?: CssVariablesMeta
26
+ clear?: boolean
27
+ children?: React.ReactNode
28
+ }
29
+
30
+ export const CssVariables: React.ComponentType<CssVariablesProps>
31
+
32
+ export const palette: Record<string, any>
33
+
34
+ export function generateColors (
35
+ palette: Record<string, any>,
36
+ overrides?: Record<string, any>
37
+ ): Record<string, any>
38
+
39
+ export function useCssVariablesMeta (options: {
40
+ staticOverrides?: Record<string, any>
41
+ palette?: Record<string, any>
42
+ colors?: Record<string, any>
43
+ componentColors?: Record<string, any>
44
+ }): CssVariablesMeta | undefined
45
+
46
+ export const StyleContext: React.Context<any>
47
+
48
+ export class Palette {
49
+ constructor (palette?: Record<string, any>)
50
+ colors: Record<string, any>
51
+ generateColors (overrides?: Record<string, any>, componentOverrides?: Record<string, any>): Record<string, any>
52
+ Color (name: string, level?: any, options?: { alpha?: number }): any
53
+ }
54
+
55
+ export const Colors: Record<string, string>
56
+
57
+ export const ThemeProvider: React.Provider<any>
58
+
59
+ export const ThemeContext: React.Context<any>
60
+
61
+ export interface GetColorOptions {
62
+ prefix?: string
63
+ convertToString?: boolean
64
+ }
65
+
66
+ export type ColorValue = string | undefined
67
+
68
+ export type GetColor = (color?: string, options?: GetColorOptions) => ColorValue
69
+
70
+ export function useColors (): GetColor
71
+
72
+ export function useMedia (): any
73
+
74
+ export interface ThemedOptions {
75
+ name?: string
76
+ }
77
+
78
+ export function themed<P> (name: string, component: React.ComponentType<P>): React.ComponentType<P>
79
+ export function themed<P> (component: React.ComponentType<P>): React.ComponentType<P>
package/index.js ADDED
@@ -0,0 +1,15 @@
1
+ export { default as u } from './helpers/u.js'
2
+ export { default as colorToRGBA } from './helpers/colorToRGBA.js'
3
+ export { default as themed } from './theming/themed.js'
4
+ export { default as palette } from './theming/palette.json'
5
+ export { default as generateColors } from './theming/generateColors.js'
6
+ export { default as getCssVariable } from './theming/getCssVariable.js'
7
+ export { default as CssVariables } from './theming/CssVariables.js'
8
+ export { default as useCssVariablesMeta } from './theming/useCssVariablesMeta.js'
9
+ export { default as StyleContext } from './theming/StyleContext.js'
10
+ export { default as Palette } from './theming/Palette.js'
11
+ export { default as Colors } from './theming/Colors.js'
12
+ export { default as ThemeProvider } from './theming/ThemeProvider.js'
13
+ export { default as ThemeContext } from './theming/ThemeContext.js'
14
+ export { default as useColors } from './hooks/useColors.js'
15
+ export { default as useMedia } from './hooks/useMedia.js'
package/package.json CHANGED
@@ -4,8 +4,23 @@
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "version": "0.1.1",
7
+ "version": "0.1.3",
8
8
  "type": "module",
9
+ "main": "index.js",
10
+ "exports": {
11
+ ".": "./index.js"
12
+ },
13
+ "dependencies": {
14
+ "@nx-js/observer-util": "^4.1.3",
15
+ "color": "^3.1.2",
16
+ "lodash": "^4.17.20"
17
+ },
18
+ "peerDependencies": {
19
+ "lodash": "^4.17.20",
20
+ "react": "*",
21
+ "react-native": "*",
22
+ "startupjs": "*"
23
+ },
9
24
  "license": "MIT",
10
- "gitHead": "da5f3c2a20f6d976d8c48f679a1242ca98217f00"
25
+ "gitHead": "fd964ebc3892d3dd0a6c85438c0af619cc50c3f0"
11
26
  }
@@ -0,0 +1,74 @@
1
+ $UI.colors = {
2
+ mainText: $UI.palette.black,
3
+ secondaryText: rgba($UI.palette.black, 0.5),
4
+
5
+ white: $UI.palette.white,
6
+ whiteLight: rgba($UI.palette.white, 0.5),
7
+ whiteLighter: rgba($UI.palette.white, 0.25),
8
+ whiteLightest: rgba($UI.palette.white, 0.05),
9
+
10
+ dark: $UI.palette.black,
11
+ darkLight: rgba($UI.palette.black, 0.5),
12
+ darkLighter: rgba($UI.palette.black, 0.25),
13
+ darkLightest: rgba($UI.palette.black, 0.05),
14
+
15
+ primary: $UI.palette.blue,
16
+ primaryLight: rgba($UI.palette.blue, 0.5),
17
+ primaryLighter: rgba($UI.palette.blue, 0.25),
18
+ primaryLightest: rgba($UI.palette.blue, 0.05),
19
+
20
+ secondary: $UI.palette.black,
21
+ secondaryLight: rgba($UI.palette.black, 0.5),
22
+ secondaryLighter: rgba($UI.palette.black, 0.25),
23
+ secondaryLightest: rgba($UI.palette.black, 0.05),
24
+
25
+ success: $UI.palette.green,
26
+ successLight: rgba($UI.palette.green, 0.5),
27
+ successLighter: rgba($UI.palette.green, 0.25),
28
+ successLightest: rgba($UI.palette.green, 0.05),
29
+
30
+ warning: $UI.palette.yellow,
31
+ warningLight: rgba($UI.palette.yellow, 0.5),
32
+ warningLighter: rgba($UI.palette.yellow, 0.25),
33
+ warningLightest: rgba($UI.palette.yellow, 0.05),
34
+
35
+ error: $UI.palette.red,
36
+ errorLight: rgba($UI.palette.red, 0.5),
37
+ errorLighter: rgba($UI.palette.red, 0.25),
38
+ errorLightest: rgba($UI.palette.red, 0.05),
39
+
40
+ attention: $UI.palette.red,
41
+ attentionLight: rgba($UI.palette.red, 0.5),
42
+ attentionLighter: rgba($UI.palette.red, 0.25),
43
+ attentionLightest: rgba($UI.palette.red, 0.05),
44
+
45
+ additional0: $UI.palette.orange,
46
+ additional0Light: rgba($UI.palette.orange, 0.5),
47
+ additional0Lighter: rgba($UI.palette.orange, 0.25),
48
+ additional0Lightest: rgba($UI.palette.orange, 0.05),
49
+
50
+ additional1: $UI.palette.cyan,
51
+ additional1Light: rgba($UI.palette.cyan, 0.5),
52
+ additional1Lighter: rgba($UI.palette.cyan, 0.25),
53
+ additional1Lightest: rgba($UI.palette.cyan, 0.05),
54
+
55
+ additional2: $UI.palette.purple,
56
+ additional2Light: rgba($UI.palette.purple, 0.5),
57
+ additional2Lighter: rgba($UI.palette.purple, 0.25),
58
+ additional2Lightest: rgba($UI.palette.purple, 0.05),
59
+
60
+ additional3: $UI.palette.lime,
61
+ additional3Light: rgba($UI.palette.lime, 0.5),
62
+ additional3Lighter: rgba($UI.palette.lime, 0.25),
63
+ additional3Lightest: rgba($UI.palette.lime, 0.05),
64
+
65
+ additional4: $UI.palette.ochre,
66
+ additional4Light: rgba($UI.palette.ochre, 0.5),
67
+ additional4Lighter: rgba($UI.palette.ochre, 0.25),
68
+ additional4Lightest: rgba($UI.palette.ochre, 0.05),
69
+
70
+ additional5: $UI.palette.violet,
71
+ additional5Light: rgba($UI.palette.violet, 0.5),
72
+ additional5Lighter: rgba($UI.palette.violet, 0.25),
73
+ additional5Lightest: rgba($UI.palette.violet, 0.05)
74
+ }
@@ -0,0 +1,82 @@
1
+ from(num)
2
+ condition = 'screen and (min-width: %s)' % num
3
+ @media condition
4
+ {block}
5
+
6
+ to(num)
7
+ condition = 'screen and (max-width: %s)' % ((num - 1))
8
+ @media condition
9
+ {block}
10
+
11
+ // DEPRECATED
12
+ mobile()
13
+ +to($UI.media.mobile)
14
+ {block}
15
+
16
+ tablet()
17
+ +from($UI.media.tablet)
18
+ {block}
19
+
20
+ desktop()
21
+ +from($UI.media.desktop)
22
+ {block}
23
+
24
+ wide()
25
+ +from($UI.media.wide)
26
+ {block}
27
+
28
+ between(num1, num2)
29
+ condition = 'screen and (min-width: %s) and (max-width: %s)' % (num1 (num2 - 1))
30
+ @media condition
31
+ {block}
32
+
33
+ betweenHeight(num1, num2)
34
+ condition = 'screen and (min-height: %s) and (max-height: %s)' % (num1 (num2 - 1))
35
+ @media condition
36
+ {block}
37
+
38
+ portrait()
39
+ @media (orientation: portrait)
40
+ {block}
41
+
42
+ landscape()
43
+ @media (orientation: landscape)
44
+ {block}
45
+
46
+ web()
47
+ if __WEB__ is defined
48
+ {block}
49
+
50
+ android()
51
+ if __ANDROID__ is defined
52
+ {block}
53
+
54
+ ios()
55
+ if __IOS__ is defined
56
+ {block}
57
+
58
+ windows()
59
+ if __WINDOWS__ is defined
60
+ {block}
61
+
62
+ macos()
63
+ if __MACOS__ is defined
64
+ {block}
65
+
66
+ native()
67
+ unless __WEB__ is defined
68
+ {block}
69
+
70
+ bleed(left = 2u, right = left)
71
+ padding-left left
72
+ padding-right right
73
+ margin-left (- left)
74
+ margin-right (- right)
75
+
76
+ radius(key = m)
77
+ if key is m
78
+ border-radius 4px
79
+ else if key is l
80
+ border-radius 8px
81
+ else if key is circle
82
+ border-radius 9999px
@@ -0,0 +1,8 @@
1
+ if !($UI is defined)
2
+ $UI = {}
3
+ @require('./palette')
4
+ @require('./colors')
5
+ @require('./variables')
6
+ @require('./shadows')
7
+ @require('./helpers')
8
+ @require('./typography')
@@ -0,0 +1,14 @@
1
+ $UI.palette = {
2
+ white: #fff,
3
+ black: #3E4657,
4
+ blue: #2962FF,
5
+ violet: #6772E5,
6
+ green: #24B47E,
7
+ yellow: #F5BE59,
8
+ red: #E25950,
9
+ orange: #FF7900,
10
+ cyan: #00AED6,
11
+ purple: #B200FF,
12
+ lime: #A6D800,
13
+ ochre: #F5A623
14
+ }
@@ -0,0 +1,34 @@
1
+ $UI.shadows = {
2
+ '0': {
3
+ // HACK: 'box-shadow none' does not work correctly on ios
4
+ // it darkens all View component with background in project
5
+ // and it blurs text when there is no background-color is set
6
+ // therefore we using 'box-shadow 0 0 0 rgba(black, 0)'
7
+ box-shadow: 0 0 0 rgba(black, 0)
8
+ elevation: 0
9
+ },
10
+ '1': {
11
+ box-shadow: 0 1px 2px var(--color-shadow-main)
12
+ elevation: 3
13
+ },
14
+ '2': {
15
+ box-shadow: 0 3px 5px var(--color-shadow-main-strong)
16
+ elevation: 6
17
+ },
18
+ '3': {
19
+ box-shadow: 0 5px 8px var(--color-shadow-main-strong)
20
+ elevation: 12
21
+ },
22
+ '4': {
23
+ box-shadow: 0 8px 12px var(--color-shadow-main)
24
+ elevation: 18
25
+ }
26
+ }
27
+
28
+ shadow(level = 1)
29
+ _shadow = $UI.shadows['' + level]
30
+ if (_shadow) {
31
+ {_shadow}
32
+ } else {
33
+ error('ERROR! Wrong shadow level ' + level + ' passed to shadow() mixin. Such level does not exist in $UI.shadows')
34
+ }
@@ -0,0 +1,99 @@
1
+ $fontWeightNamesMap = {
2
+ '100': 'Thin',
3
+ '200': 'ExtraLight',
4
+ '300': 'Light',
5
+ '400': 'Regular',
6
+ '500': 'Medium',
7
+ '600': 'SemiBold',
8
+ '700': 'Bold',
9
+ '800': 'ExtraBold'
10
+ '900': 'Black',
11
+ normal: 'Regular',
12
+ bold: 'Bold'
13
+ }
14
+
15
+ DEPRECATED_SIZES = default xs 's' m l xl xxl xxxl xxxxl xxxxxl
16
+
17
+ font(size = $UI.defaultFontSize, weight = $UI.fontWeights.normal)
18
+ // Workaround global built-in function s()
19
+ // http://stylus-lang.com/docs/bifs.html#sfmt-
20
+ size = 's' if size is s
21
+ size = body2 if size is default // DEPRECATED
22
+
23
+ if size in DEPRECATED_SIZES
24
+ p('font() mixin: size ' + size + ' is deprecated')
25
+
26
+ fontFamily($UI.fontFamilies[size], $UI.fontWeights[size] || weight)
27
+
28
+ font-size: $UI.fontSizes[size]
29
+ line-height: $UI.lineHeights[size]
30
+
31
+ if $UI.letterSpacings && $UI.letterSpacings[size]
32
+ letter-spacing: $UI.letterSpacings[size]
33
+
34
+ if $UI.textTransforms && $UI.textTransforms[size]
35
+ text-transform: $UI.textTransforms[size]
36
+
37
+ text(key = default) // DEPRECATED
38
+ p('text() mixin is deprecated, use font() instead')
39
+ // color
40
+ if key is description
41
+ color: var(--color-text-description)
42
+ else
43
+ color: var(--color-text-main)
44
+
45
+ // font, line
46
+ if key is default
47
+ font()
48
+ else if key is description
49
+ font()
50
+ else if key is h1
51
+ font(xxxxxl)
52
+ else if key is h2
53
+ font(xxxxl)
54
+ else if key is h3
55
+ font(xxxl)
56
+ else if key is h4
57
+ font(xxl)
58
+ else if key is h5
59
+ font(xl)
60
+ else if key is h6
61
+ font(l)
62
+
63
+ fontFamily(
64
+ fontName = 'normal',
65
+ fontWeight = $UI.fontWeights.normal,
66
+ fontStyle = 'normal'
67
+ )
68
+ fontName = fontName or 'normal'
69
+ fontWeight = fontWeight or $UI.fontWeights.normal
70
+ fontStyle = fontStyle or 'normal'
71
+
72
+ defaultFontFamilies = $UI.fontFamilies.default || {}
73
+ platformFontFamilies = $UI.fontFamilies[$PLATFORM] || {}
74
+ fontFamily = defaultFontFamilies[fontName] or platformFontFamilies[fontName] or fontName
75
+
76
+ if (isCustomFont(fontFamily)) {
77
+ thickness = $fontWeightNamesMap[fontWeight]
78
+ isRegular = thickness is 'Regular'
79
+ isItalic = fontStyle is italic
80
+
81
+ fontFamily += '-'
82
+ // add thickness
83
+ // don't add thickness to font family name if regular and italic
84
+ if (!isRegular || !isItalic) {
85
+ fontFamily += $fontWeightNamesMap['' + fontWeight]
86
+ }
87
+ // add style
88
+ if (isItalic) {
89
+ fontFamily += 'Italic'
90
+ }
91
+ } else {
92
+ font-weight fontWeight
93
+ font-style fontStyle
94
+ }
95
+
96
+ font-family fontFamily
97
+
98
+ isCustomFont(fontFamily)
99
+ return index($UI.customFontFamilies, fontFamily) isnt null