@startupjs-ui/color-picker 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 +20 -0
- package/README.mdx +38 -0
- package/helpers.ts +17 -0
- package/index.cssx.styl +15 -0
- package/index.d.ts +23 -0
- package/index.tsx +75 -0
- package/package.json +25 -0
- package/picker.tsx +45 -0
- package/picker.web.tsx +51 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
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/color-picker
|
|
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))
|
|
20
|
+
* **color-picker:** refactor ColorPicker component ([96b24fe](https://github.com/startupjs/startupjs-ui/commit/96b24feeb2fc0cb85e30fe1ae1e03d9fca741f4c))
|
package/README.mdx
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { useState } from 'react'
|
|
2
|
+
import ColorPicker, { _PropsJsonSchema as ColorPickerPropsJsonSchema } from './index'
|
|
3
|
+
import { Sandbox } from '@startupjs-ui/docs'
|
|
4
|
+
|
|
5
|
+
# ColorPicker
|
|
6
|
+
|
|
7
|
+
ColorPicker allows user to select a color from the color palette (works with colors in hexadecimal format).
|
|
8
|
+
|
|
9
|
+
## Import
|
|
10
|
+
|
|
11
|
+
```jsx
|
|
12
|
+
import { ColorPicker } from 'startupjs-ui'
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Simple example
|
|
16
|
+
|
|
17
|
+
```jsx example
|
|
18
|
+
const [color, setColor] = useState()
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<ColorPicker
|
|
22
|
+
value={color}
|
|
23
|
+
onChangeColor={setColor}
|
|
24
|
+
/>
|
|
25
|
+
)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Sandbox
|
|
29
|
+
|
|
30
|
+
<Sandbox
|
|
31
|
+
Component={ColorPicker}
|
|
32
|
+
propsJsonSchema={ColorPickerPropsJsonSchema}
|
|
33
|
+
props={{
|
|
34
|
+
value: '#FF0000',
|
|
35
|
+
onChangeColor: value => alert('Color ' + value + ' is selected')
|
|
36
|
+
}}
|
|
37
|
+
block
|
|
38
|
+
/>
|
package/helpers.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import Color from 'color'
|
|
2
|
+
|
|
3
|
+
export function getLabelColor (hex: string): string {
|
|
4
|
+
try {
|
|
5
|
+
const threshold = 0.5
|
|
6
|
+
const rgbColor = Color(hex).object()
|
|
7
|
+
const r = rgbColor.r * 0.2126
|
|
8
|
+
const g = rgbColor.g * 0.7152
|
|
9
|
+
const b = rgbColor.b * 0.0722
|
|
10
|
+
const lightness = (r + g + b) / 255
|
|
11
|
+
const textColor = lightness >= threshold ? 'black' : 'white'
|
|
12
|
+
return textColor
|
|
13
|
+
} catch (err) {
|
|
14
|
+
console.error('[getLabelColor]: Invalid hex color')
|
|
15
|
+
return 'gray'
|
|
16
|
+
}
|
|
17
|
+
}
|
package/index.cssx.styl
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
.button
|
|
2
|
+
border-color: var(--color-border-main)
|
|
3
|
+
border-width 1px
|
|
4
|
+
|
|
5
|
+
.content
|
|
6
|
+
flex-grow 1
|
|
7
|
+
justify-content center
|
|
8
|
+
|
|
9
|
+
.picker
|
|
10
|
+
height 50u
|
|
11
|
+
// we hacked height because react-native-color-picker has a strange logic of
|
|
12
|
+
// sizing and positioning of picker.
|
|
13
|
+
// https://github.com/instea/react-native-color-picker/blob/master/src/HoloColorPicker.tsx#L114
|
|
14
|
+
// https://github.com/instea/react-native-color-picker/blob/master/src/HoloColorPicker.tsx#L331
|
|
15
|
+
// TODO: make a PR with correct behaviour to react-native-color-picker library
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
// DO NOT MODIFY THIS FILE - IT IS AUTOMATICALLY GENERATED ON COMMITS.
|
|
3
|
+
|
|
4
|
+
import { type RefObject } from 'react';
|
|
5
|
+
import { type StyleProp, type ViewStyle } from 'react-native';
|
|
6
|
+
import './index.cssx.styl';
|
|
7
|
+
declare const _default: import("react").ComponentType<ColorPickerProps>;
|
|
8
|
+
export default _default;
|
|
9
|
+
export declare const _PropsJsonSchema: {};
|
|
10
|
+
export interface ColorPickerProps {
|
|
11
|
+
/** Custom styles applied to the root view */
|
|
12
|
+
style?: StyleProp<ViewStyle>;
|
|
13
|
+
/** Current hex color value @default '#fff' */
|
|
14
|
+
value?: string;
|
|
15
|
+
/** Disables opening and auto-closes picker @default false */
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
/** Size of the button @default 'm' */
|
|
18
|
+
size?: 's' | 'm' | 'l';
|
|
19
|
+
/** Called with the selected hex color */
|
|
20
|
+
onChangeColor?: (color: string) => void;
|
|
21
|
+
/** Imperative ref to open/close picker */
|
|
22
|
+
ref?: RefObject<any>;
|
|
23
|
+
}
|
package/index.tsx
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useState,
|
|
3
|
+
useRef,
|
|
4
|
+
useEffect,
|
|
5
|
+
useImperativeHandle,
|
|
6
|
+
type ReactNode,
|
|
7
|
+
type RefObject
|
|
8
|
+
} from 'react'
|
|
9
|
+
import { type StyleProp, type ViewStyle } from 'react-native'
|
|
10
|
+
import { pug, observer } from 'startupjs'
|
|
11
|
+
import { themed } from '@startupjs-ui/core'
|
|
12
|
+
import Div from '@startupjs-ui/div'
|
|
13
|
+
import Button from '@startupjs-ui/button'
|
|
14
|
+
import Picker from './picker'
|
|
15
|
+
import { getLabelColor } from './helpers'
|
|
16
|
+
import './index.cssx.styl'
|
|
17
|
+
|
|
18
|
+
export default observer(themed('ColorPicker', ColorPicker))
|
|
19
|
+
|
|
20
|
+
export const _PropsJsonSchema = {/* ColorPickerProps */}
|
|
21
|
+
|
|
22
|
+
export interface ColorPickerProps {
|
|
23
|
+
/** Custom styles applied to the root view */
|
|
24
|
+
style?: StyleProp<ViewStyle>
|
|
25
|
+
/** Current hex color value @default '#fff' */
|
|
26
|
+
value?: string
|
|
27
|
+
/** Disables opening and auto-closes picker @default false */
|
|
28
|
+
disabled?: boolean
|
|
29
|
+
/** Size of the button @default 'm' */
|
|
30
|
+
size?: 's' | 'm' | 'l'
|
|
31
|
+
/** Called with the selected hex color */
|
|
32
|
+
onChangeColor?: (color: string) => void
|
|
33
|
+
/** Imperative ref to open/close picker */
|
|
34
|
+
ref?: RefObject<any>
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function ColorPicker ({
|
|
38
|
+
style,
|
|
39
|
+
size = 'm',
|
|
40
|
+
value = '#fff',
|
|
41
|
+
disabled = false,
|
|
42
|
+
onChangeColor = () => {},
|
|
43
|
+
ref
|
|
44
|
+
}: ColorPickerProps): ReactNode {
|
|
45
|
+
const [shown, setShown] = useState(false)
|
|
46
|
+
const pickerRef = useRef<any>(null)
|
|
47
|
+
|
|
48
|
+
useImperativeHandle(ref, () => pickerRef.current)
|
|
49
|
+
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
if (shown && disabled) pickerRef.current?.hide?.()
|
|
52
|
+
}, [disabled, shown])
|
|
53
|
+
|
|
54
|
+
return pug`
|
|
55
|
+
Div(style=style)
|
|
56
|
+
Picker(
|
|
57
|
+
ref=pickerRef
|
|
58
|
+
onChangeColor=(color) => {
|
|
59
|
+
onChangeColor(color)
|
|
60
|
+
setShown(false)
|
|
61
|
+
}
|
|
62
|
+
)
|
|
63
|
+
Button.button(
|
|
64
|
+
disabled=disabled
|
|
65
|
+
style={ backgroundColor: value }
|
|
66
|
+
variant='flat'
|
|
67
|
+
size=size
|
|
68
|
+
textStyle={ color: getLabelColor(value) }
|
|
69
|
+
onPress=() => {
|
|
70
|
+
pickerRef.current?.show?.()
|
|
71
|
+
setShown(true)
|
|
72
|
+
}
|
|
73
|
+
)= value.toUpperCase()
|
|
74
|
+
`
|
|
75
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@startupjs-ui/color-picker",
|
|
3
|
+
"version": "0.1.3",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public"
|
|
6
|
+
},
|
|
7
|
+
"main": "index.tsx",
|
|
8
|
+
"types": "index.d.ts",
|
|
9
|
+
"type": "module",
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"@startupjs-ui/button": "^0.1.3",
|
|
12
|
+
"@startupjs-ui/core": "^0.1.3",
|
|
13
|
+
"@startupjs-ui/div": "^0.1.3",
|
|
14
|
+
"@startupjs-ui/modal": "^0.1.3",
|
|
15
|
+
"@startupjs-ui/scroll-view": "^0.1.3",
|
|
16
|
+
"color": "^3.1.2",
|
|
17
|
+
"react-native-color-picker": "^0.6.0"
|
|
18
|
+
},
|
|
19
|
+
"peerDependencies": {
|
|
20
|
+
"react": "*",
|
|
21
|
+
"react-native": "*",
|
|
22
|
+
"startupjs": "*"
|
|
23
|
+
},
|
|
24
|
+
"gitHead": "fd964ebc3892d3dd0a6c85438c0af619cc50c3f0"
|
|
25
|
+
}
|
package/picker.tsx
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { useRef, useImperativeHandle, type ReactNode, type RefObject } from 'react'
|
|
2
|
+
import { ColorPicker as RNColorPicker } from 'react-native-color-picker'
|
|
3
|
+
import { pug, observer, $ } from 'startupjs'
|
|
4
|
+
import ScrollView from '@startupjs-ui/scroll-view'
|
|
5
|
+
import Modal from '@startupjs-ui/modal'
|
|
6
|
+
import './index.cssx.styl'
|
|
7
|
+
|
|
8
|
+
interface PickerProps {
|
|
9
|
+
onChangeColor?: (color: string) => void
|
|
10
|
+
ref?: RefObject<any>
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function FullHeightScrollView (props: any): ReactNode {
|
|
14
|
+
return pug`
|
|
15
|
+
ScrollView(
|
|
16
|
+
contentContainerStyleName='content'
|
|
17
|
+
...props
|
|
18
|
+
)
|
|
19
|
+
`
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function Picker ({
|
|
23
|
+
onChangeColor = () => {},
|
|
24
|
+
ref
|
|
25
|
+
}: PickerProps): ReactNode {
|
|
26
|
+
const $visible = useRef<any>($()).current
|
|
27
|
+
|
|
28
|
+
useImperativeHandle(ref, () => ({
|
|
29
|
+
show: () => $visible.set(true),
|
|
30
|
+
hide: () => $visible.set(false)
|
|
31
|
+
}))
|
|
32
|
+
|
|
33
|
+
return pug`
|
|
34
|
+
Modal($visible=$visible variant='fullscreen')
|
|
35
|
+
Modal.Content(ContentComponent=FullHeightScrollView)
|
|
36
|
+
RNColorPicker.picker(
|
|
37
|
+
onColorSelected=color => {
|
|
38
|
+
onChangeColor(color)
|
|
39
|
+
$visible.set(false)
|
|
40
|
+
}
|
|
41
|
+
)
|
|
42
|
+
`
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export default observer(Picker)
|
package/picker.web.tsx
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { useRef, useEffect, useImperativeHandle, type ReactNode, type RefObject } from 'react'
|
|
2
|
+
import { pug, observer } from 'startupjs'
|
|
3
|
+
import './index.cssx.styl'
|
|
4
|
+
|
|
5
|
+
interface PickerProps {
|
|
6
|
+
onChangeColor?: (color: string) => void
|
|
7
|
+
ref?: RefObject<any>
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function Picker ({
|
|
11
|
+
onChangeColor = () => {},
|
|
12
|
+
ref
|
|
13
|
+
}: PickerProps): ReactNode {
|
|
14
|
+
const pickerRef = useRef<any>(null)
|
|
15
|
+
|
|
16
|
+
useImperativeHandle(ref, () => ({
|
|
17
|
+
show: () => pickerRef.current?.click?.(),
|
|
18
|
+
hide: () => {
|
|
19
|
+
// hacky way to close the color picker
|
|
20
|
+
if (!pickerRef.current) return
|
|
21
|
+
pickerRef.current.setAttribute('type', 'text')
|
|
22
|
+
pickerRef.current.setAttribute('type', 'color')
|
|
23
|
+
}
|
|
24
|
+
}))
|
|
25
|
+
|
|
26
|
+
function onChange (e: any) {
|
|
27
|
+
onChangeColor(e.target.value)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
const colorPicker = pickerRef.current
|
|
32
|
+
if (!colorPicker) return
|
|
33
|
+
colorPicker.addEventListener('change', onChange, false)
|
|
34
|
+
return () => colorPicker.removeEventListener('change', onChange, false)
|
|
35
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
36
|
+
}, [])
|
|
37
|
+
|
|
38
|
+
return pug`
|
|
39
|
+
input(
|
|
40
|
+
ref=pickerRef
|
|
41
|
+
type='color'
|
|
42
|
+
style={
|
|
43
|
+
visibility: 'hidden',
|
|
44
|
+
position: 'absolute',
|
|
45
|
+
alignSelf: 'center'
|
|
46
|
+
}
|
|
47
|
+
)
|
|
48
|
+
`
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export default observer(Picker)
|