@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 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
+ }
@@ -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)